From patchwork Sat Aug 17 09:25:53 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: avih X-Patchwork-Id: 13767073 Received: from mail-wm1-f48.google.com (mail-wm1-f48.google.com [209.85.128.48]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 3C603148317 for ; Sat, 17 Aug 2024 09:26:05 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.48 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1723886767; cv=none; b=TTeVuy7IWZ0R3OImRgigBuuqig9xmYRPNGdNPTeZuec39exqvSybh+oTbL945etbNGEIRnIPre87zgSkTxZZO3ghVxmK0atEPiyrAIE9QGreHFEyz47HLQ7WVZvvJ+nO7n9biwp46NQhv0qLnUK1SZKrMMZEjhfAI7uTu8Lp7eo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1723886767; c=relaxed/simple; bh=sipFw1dJc1zbv6tyF/MqIbyJnlnjC/BLxSZ5WN2aGTs=; h=Message-Id:In-Reply-To:References:From:Date:Subject:Content-Type: MIME-Version:To:Cc; b=fxqNGpHwR9NlE44V6CEA6OEJO4ZtpBi2N+h5mQFsZ6cH9ANPB5ylx1uHl9UBNOMExI2+dRsUnjVeEGlpxcgTmwOmeEMYcCnVwP03rvMqukh1fPkZvxNXZAL8jX5C8lSItPQ78Dy394OvtG0LsiBnxCn3eQ6m7VvFEOI69aGyKnE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=nRyBC33Y; arc=none smtp.client-ip=209.85.128.48 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="nRyBC33Y" Received: by mail-wm1-f48.google.com with SMTP id 5b1f17b1804b1-4280ee5f1e3so20040125e9.0 for ; Sat, 17 Aug 2024 02:26:05 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1723886763; x=1724491563; darn=vger.kernel.org; h=cc:to:mime-version:content-transfer-encoding:fcc:subject:date:from :references:in-reply-to:message-id:from:to:cc:subject:date :message-id:reply-to; bh=6FG3uwywf17nE7MKTAyfOz2NJswUr1C/H8jKjMZ6nbM=; b=nRyBC33YhUqXSvQwnRHQr08Or3kvzP0iT4KkT+dtGsyF2tJziGmj4XEohpY0QFiYjn +T323GKBi//vtHRb7e0BPEeizRkUYXSaENf3AIRfdl6k8Iu5kehRnBI22iGYokuqiG9G pbCMSEBld6peKlObCK/Jizim9c0mK/rZbeRJdtU1WB1X3SPaHsiILu9wjf67MbXlasaq JjK6aavnqPDYGUAjAViMokTam8b7dPaFa/mYKnexU1ib20pVUwDoej31x6Uy9UsobqZT EFaK6w6EYj6BZgcluTcGGF07sjxC9gAWGyc5hyL2tLiF2Mxnfior8jGB4ejYbc0GlHCu xHCA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1723886763; x=1724491563; h=cc:to:mime-version:content-transfer-encoding:fcc:subject:date:from :references:in-reply-to:message-id:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=6FG3uwywf17nE7MKTAyfOz2NJswUr1C/H8jKjMZ6nbM=; b=MTMC51VXa79ZoV3dCjN4DF7Hcb+JRrWd1hR6r58C3kToIZxS8cNYExBIUD+Dqlgv+l B0gvv/arkdB1ZqA9Y4vEQ3MlpKTyFoYloku/FYO4UyVv3qaQ0vIlt+c+ONiKvQed7h4Z iw9DukTvFqxIXzYeYv42KQGN7z846yyy4f+M5/2xNrocgeRbEWiyXIStVUiIH2LG8qrK d69C8INZLjl2qBA6eFkfllhiVM6/oMXkEDwnwkdLe/oS1sLu1qK0ynnpjvBHPS7oqvVO DxOXGIDAzJBjMfn4IYfX1vPauy4XVB1AsnOjE27cfjW48NP2M6lMLjBPrvWXP7crSAmh vNIg== X-Gm-Message-State: AOJu0YyVnK6Orz+guGYnhx5GMdd9QhpTSrkvsB6qutkpvhVF4BRqhUWO 7SIPV04Hk2BswCPqUBnAIfSDK/FmzQpq2MXuepR7yUVJYXLoYLEw/2MpAQ== X-Google-Smtp-Source: AGHT+IHk/t3c6xlORAIaMIB/QG5YmStoCryfdxaP5oJUNKbu9+Nsm5YACEWd1zq2shHgGfKpIw3cmw== X-Received: by 2002:a05:600c:1897:b0:42a:a6aa:4135 with SMTP id 5b1f17b1804b1-42aa6aa45f2mr24732695e9.20.1723886762962; Sat, 17 Aug 2024 02:26:02 -0700 (PDT) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-429ed6586c4sm45112555e9.24.2024.08.17.02.26.02 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 17 Aug 2024 02:26:02 -0700 (PDT) Message-Id: <9ce5ddadf0bb13229461d67451094a373348771e.1723886760.git.gitgitgadget@gmail.com> In-Reply-To: References: Date: Sat, 17 Aug 2024 09:25:53 +0000 Subject: [PATCH v3 1/8] git-prompt: use here-doc instead of here-string Fcc: Sent Precedence: bulk X-Mailing-List: git@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 To: git@vger.kernel.org Cc: "Junio C. Hamano" , "brian m. carlson" , Patrick Steinhardt , Avi Halachmi , "Avi Halachmi (:avih)" From: "Avi Halachmi (:avih)" From: "Avi Halachmi (:avih)" Here-documend is standard, and works in all shells. Both here-string and here-doc add final newline, which is important in this case, because $output is without final newline, but we do want "read" to succeed on the last line as well. Shells which support here-string: - bash, zsh, mksh, ksh93, yash (non-posix-mode). shells which don't, and got fixed: - ash-derivatives (dash, free/net bsd sh, busybox-ash). - pdksh, openbsd sh. - All Schily Bourne shell variants. Signed-off-by: Avi Halachmi (:avih) --- contrib/completion/git-prompt.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/contrib/completion/git-prompt.sh b/contrib/completion/git-prompt.sh index 5330e769a72..ebf2e30d684 100644 --- a/contrib/completion/git-prompt.sh +++ b/contrib/completion/git-prompt.sh @@ -137,7 +137,9 @@ __git_ps1_show_upstream () upstream_type=svn+git # default upstream type is SVN if available, else git ;; esac - done <<< "$output" + done <<-OUTPUT + $output + OUTPUT # parse configuration values local option From patchwork Sat Aug 17 09:25:54 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: avih X-Patchwork-Id: 13767075 Received: from mail-wr1-f53.google.com (mail-wr1-f53.google.com [209.85.221.53]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id BD73614831D for ; Sat, 17 Aug 2024 09:26:06 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.53 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1723886768; cv=none; b=OxzEs74CGhqccCrTAlaCt1CeNSjXkKp1/NtS4q0g5QKZomk7gpC7uvrcSSK4p1wxALQpJIoYWKWdZQ4sqsmHzH3SaFLZ+YzR5J4Ta9lbMcw9DoQvJ5r+pZZDjQh/0bz7QgZS9RZ9v9ZzdNwRxsVspY11ylq9D6KtV5w0Ns5vC4s= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1723886768; c=relaxed/simple; bh=PeWD7Xzsyt+Jh9Nqsn4TpYWX2egoJFqBtWAUMS9nZWQ=; h=Message-Id:In-Reply-To:References:From:Date:Subject:Content-Type: MIME-Version:To:Cc; b=sbrJ5jU6+P0a3GuJM6Kygw/olv3HKvV43qBBP8LiS/8sRYiDj6QqG65jjhftSpmhBAY7fj9PhCQtuUmGjxnlM2fzsyGmMM9kPkgxTWDXZOjJ72FY4dNtHXDJQfa3bdmb0XQVn1eYms/py4b9D4MCZOcPAJbBH6ItvXY2rEILOSA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=PV+u69nP; arc=none smtp.client-ip=209.85.221.53 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="PV+u69nP" Received: by mail-wr1-f53.google.com with SMTP id ffacd0b85a97d-3718ca50fd7so1419140f8f.1 for ; Sat, 17 Aug 2024 02:26:06 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1723886764; x=1724491564; darn=vger.kernel.org; h=cc:to:mime-version:content-transfer-encoding:fcc:subject:date:from :references:in-reply-to:message-id:from:to:cc:subject:date :message-id:reply-to; bh=bffUfw/AShNzuPzmr6Fl68h5i7kGOyEHgnQZYZFtG8Q=; b=PV+u69nPyI+dao45hDjCJjNoHMDrGe2tBKCtf4zjIqKTkNZR8IGERNFE4mNwl1hlUi ylC1nqYd3MkmfHK2QriTG1ilcsIjJXKDWhm16dBTj7TNT4XL3R8V++LGQNAwjeXhJn6Z zOEkfKvDWmMMfjj3dQQ+pvFyPvRZQPc9zzpZ1sm+Mz5YucMWZVQ7X/3x1rJpnsNdaknB er4KsjEyt3qVxzDeoKpQ7Zney378Zd8bC/yx8fgj33EzjR3KJaQ01YZlSOYoBlnGBbWP ZqtYqYNzvruZV8ivu+T73/X2LzTTIkjSvc9miXZfVn10MaEmP64Ck0NIr8/Uv2hluBcn Y30Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1723886764; x=1724491564; h=cc:to:mime-version:content-transfer-encoding:fcc:subject:date:from :references:in-reply-to:message-id:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=bffUfw/AShNzuPzmr6Fl68h5i7kGOyEHgnQZYZFtG8Q=; b=Zj6WKFnMhRfSvsOIiUKEvwi4m2cSI1JDUmDBWX/lsBfM4E/xkKn/72Qb80mKMwedm0 z0XECesoRe8oz7IM1DTJvtGxxO9MTM61Y3tNQUHPS79muM6FMKbFqdFRGM1WTELSclGM DdbsresJEhFqMp+wLzX7M2ImF6gCwLt2G9HyY055BP1AW5uPtt1yARJPQu9P6MflgP7W DFN9/qMjKY99wPN9DbTkh7jKrsdUgsAUqVpLYnSFdyMo9WrA+EfRHX7r9Ozos/nmhNzR rXqgXH4VWLbrfoRmPsKF9hGZX9vhzRGC6s+u9yGazzx2EH5eQ84dn2+PS+eM2h9howiI 4JsA== X-Gm-Message-State: AOJu0YwKtOzGeN2Zn7zxEDbxlI4FTk+FX3i44XciRz61XjQ2Nv8hOhgf Cc8HIr6mfwMbJFvJRurb4n558g1vSGBwgYy+f3JvuNOfFJb/jVNt8pb6ag== X-Google-Smtp-Source: AGHT+IHnpl7IIWCEXgubz87Orj9DemIiK2m+Qw4jbvpYOKftE4fp4/fk//2DkYFV2bcmcb0uc/C9og== X-Received: by 2002:a5d:424e:0:b0:371:9366:6d8d with SMTP id ffacd0b85a97d-37194328b5amr3445376f8f.19.1723886764285; Sat, 17 Aug 2024 02:26:04 -0700 (PDT) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-371898aacf9sm5419978f8f.102.2024.08.17.02.26.03 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 17 Aug 2024 02:26:03 -0700 (PDT) Message-Id: <680ecb524040c64f886c4e484a64f0d17b512e27.1723886760.git.gitgitgadget@gmail.com> In-Reply-To: References: Date: Sat, 17 Aug 2024 09:25:54 +0000 Subject: [PATCH v3 2/8] git-prompt: fix uninitialized variable Fcc: Sent Precedence: bulk X-Mailing-List: git@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 To: git@vger.kernel.org Cc: "Junio C. Hamano" , "brian m. carlson" , Patrick Steinhardt , Avi Halachmi , "Avi Halachmi (:avih)" From: "Avi Halachmi (:avih)" From: "Avi Halachmi (:avih)" First use is in the form: local var; ...; var=$var$whatever... If the variable was unset (as bash and others do after "local x"), then it would error if set -u is in effect. Also, many shells inherit the existing value after "local var" without init, but in this case it's unlikely to have a prior value. Now we initialize it. (local var= is enough, but local var="" is the custom in this file) Signed-off-by: Avi Halachmi (:avih) --- contrib/completion/git-prompt.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/completion/git-prompt.sh b/contrib/completion/git-prompt.sh index ebf2e30d684..4cc2cf91bb6 100644 --- a/contrib/completion/git-prompt.sh +++ b/contrib/completion/git-prompt.sh @@ -116,7 +116,7 @@ printf -v __git_printf_supports_v -- '%s' yes >/dev/null 2>&1 __git_ps1_show_upstream () { local key value - local svn_remote svn_url_pattern count n + local svn_remote svn_url_pattern="" count n local upstream_type=git legacy="" verbose="" name="" svn_remote=() From patchwork Sat Aug 17 09:25:55 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: avih X-Patchwork-Id: 13767076 Received: from mail-wm1-f51.google.com (mail-wm1-f51.google.com [209.85.128.51]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7F4F61487D5 for ; Sat, 17 Aug 2024 09:26:07 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.51 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1723886769; cv=none; b=S89543o4L8OrRaehRKK8c10hPg0jdYkKm6uahN+QgJkOaxEx/xV2hL2A+gkVX9GOO4tewzN69IeZr6AyY4ASNynG9ihwn1nEJnuZHBpQrE4fnx74wvjCla22B+ACFW+gL+wNvJn+4Tfk/7XOiceAlV/JmaxAAPS0uMzP80dcrV0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1723886769; c=relaxed/simple; bh=p/jqA9gX8l00DDL8hIGrnZJ3zN3+zLxdtSLBkGRh4Gs=; h=Message-Id:In-Reply-To:References:From:Date:Subject:Content-Type: MIME-Version:To:Cc; b=HysXijV/HaE0re8c77nUM1jKx+eN/sPyRVWg6JXV7AxYQdGGVv50SzvymDgXhuSUi7+jRsfkUkRzUAQgJeXYH5qAiPGqMF76fCzDwJWj40OGM0ZXJpDQItmW+39YfVq1I3APtyhyXF0GdoJPnd3JMK+iV9QRPnON5kX/QZ0xJUQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=Qo2wYrQL; arc=none smtp.client-ip=209.85.128.51 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="Qo2wYrQL" Received: by mail-wm1-f51.google.com with SMTP id 5b1f17b1804b1-429c4a4c6a8so20567035e9.0 for ; Sat, 17 Aug 2024 02:26:07 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1723886765; x=1724491565; darn=vger.kernel.org; h=cc:to:mime-version:content-transfer-encoding:fcc:subject:date:from :references:in-reply-to:message-id:from:to:cc:subject:date :message-id:reply-to; bh=scQQcYhZj7QegWybZvw4rIUqVDfa3YFL+8LLt/4ZwzY=; b=Qo2wYrQLF2bAUxb4QTN45rFzVGi5/kxQlLGuF/NPNn+81fdxTjTThniMqKTn3gLQZj jDoLfcjzIz0Xipf5hUmMKU3z0YBeVGrEZfRlW9m0d0/y45PhhomjoQVapPa6/Q6mmWaw r6Y3fmX4xm1mZltOTQUDb9kHauMFpl317Gvh7XYSVyviTHxskf0iTRNk1nAoTcCG3yty AuT6Oa9gE+Sqq4D9E+Njh/4JClsCqCwsyYs5Ernt029n3X3pzQqZu3xX/AdCcBuANe7a tlbRGd6hvesrWnVK2wPqtUKrv5DkqzcrwuHfWan8WWoGfg7s2wNFehxX6gXWaRTeIbWb 03dA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1723886765; x=1724491565; h=cc:to:mime-version:content-transfer-encoding:fcc:subject:date:from :references:in-reply-to:message-id:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=scQQcYhZj7QegWybZvw4rIUqVDfa3YFL+8LLt/4ZwzY=; b=jXIwcC7ehMD2MpSjqqJpF7svTnLwO+HqiVN5SnEXI0BuGMqtTM+6hQJ4wetWt96erm VniSTxHR1+nJiFHyCS1k9VNKZrLyn3+hGE/bYv9qSt5LUmefpd1a4/U2QttJKl7S8Opy wfmamMmVfIoLZFcrybcrCohM082wFGeWdON5qW1OwDB2H+R+82thFytRqmeOQ1lCxHro Ogu2DUkc3UTB6oBtkXVoZ63LqFN2ri6iFy4gFc8SjuJg/mJcHlN0BGQAF36oB50uw+qM 0nTWPq3fUb2NYiCzyFa9H9BGe6OviWAluvu4tIu5IEAw7GoFVE1yxnPfZJvnM0NCmgQL fvFQ== X-Gm-Message-State: AOJu0Yy5UYK5z4orTfi0U3cE+c2T1eDQL4KsaWA4YqL49irRd3/LDNPW mbQQpMmIHqNpe54bNFLtwh28QVxDO+IXk5V+uvux59XnAwm8b+S3eApsPg== X-Google-Smtp-Source: AGHT+IETgo8nX4eIylgHBu51Gek20ZiWP3/zV44CrV+f23JWVdcjYlrLWaNcsEJbZxa8PlzSGi3ayA== X-Received: by 2002:a05:600c:500a:b0:426:5416:67de with SMTP id 5b1f17b1804b1-429ed7e44c3mr33421485e9.30.1723886765040; Sat, 17 Aug 2024 02:26:05 -0700 (PDT) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-429ded71ef0sm98358415e9.36.2024.08.17.02.26.04 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 17 Aug 2024 02:26:04 -0700 (PDT) Message-Id: <7e994eae7bc3dfa021262410c801ddb124ce24f1.1723886760.git.gitgitgadget@gmail.com> In-Reply-To: References: Date: Sat, 17 Aug 2024 09:25:55 +0000 Subject: [PATCH v3 3/8] git-prompt: don't use shell arrays Fcc: Sent Precedence: bulk X-Mailing-List: git@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 To: git@vger.kernel.org Cc: "Junio C. Hamano" , "brian m. carlson" , Patrick Steinhardt , Avi Halachmi , "Avi Halachmi (:avih)" From: "Avi Halachmi (:avih)" From: "Avi Halachmi (:avih)" Arrays only existed in the svn-upstream code, used to: - Keep a list of svn remotes. - Convert commit msg to array of words, extract the 2nd-to-last word. Except bash/zsh, nearly all shells failed load on syntax errors here. Now: - The svn remotes are a list of newline-terminated values. - The 2nd-to-last word is extracted using standard shell substrings. - All shells can digest the svn-upstream code. While using shell field splitting to extract the word is simple, and doesn't even need non-standard code, e.g. set -- $(git log -1 ...), it would have the same issues as the old array code: it depends on IFS which we don't control, and it's subject to glob-expansion, e.g. if the message happens to include * or **/* (as this commit message just did), then the array could get huge. This was not great. Now it uses standard shell substrings, and we know the exact delimiter to expect, because it's the match from our grep just one line earlier. The new word extraction code also fixes svn-upstream in zsh, because previously it used arr[len-2], but because in zsh, unlike bash, array subscripts are 1-based, it incorrectly extracted the 3rd-to-last word. symptom: missing upstream status in a git-svn repo: u=, u+N-M, etc. The breakage in zsh is surprising, because it was last touched by commit d0583da838 (prompt: fix show upstream with svn and zsh), claiming to fix exactly that. However, it only mentions syntax fixes. It's unclear if behavior was fixed too. But it was broken, now fixed. Note LF=$'\n' and then using $LF instead of $'\n' few times. A future commit will add fallback for shells without $'...', so this would be the only line to touch instead of replacing every $'\n' . Shells which could run the previous array code: - bash Shells which have arrays but were broken anyway: - zsh: 1-based subscript - ksh93: no "local" (the new code can't fix this part...) - mksh, openbsd sh, pdksh: failed load on syntax error: "for ((...))". More shells which Failed to load due to syntax error: - dash, free/net bsd sh, busybox-ash, Schily Bourne shell, yash. Signed-off-by: Avi Halachmi (:avih) --- contrib/completion/git-prompt.sh | 48 ++++++++++++++++++++------------ 1 file changed, 30 insertions(+), 18 deletions(-) diff --git a/contrib/completion/git-prompt.sh b/contrib/completion/git-prompt.sh index 4cc2cf91bb6..75c3a813fda 100644 --- a/contrib/completion/git-prompt.sh +++ b/contrib/completion/git-prompt.sh @@ -116,10 +116,10 @@ printf -v __git_printf_supports_v -- '%s' yes >/dev/null 2>&1 __git_ps1_show_upstream () { local key value - local svn_remote svn_url_pattern="" count n + local svn_remotes="" svn_url_pattern="" count n local upstream_type=git legacy="" verbose="" name="" + local LF=$'\n' - svn_remote=() # get some config options from git-config local output="$(git config -z --get-regexp '^(svn-remote\..*\.url|bash\.showupstream)$' 2>/dev/null | tr '\0\n' '\n ')" while read -r key value; do @@ -132,7 +132,7 @@ __git_ps1_show_upstream () fi ;; svn-remote.*.url) - svn_remote[$((${#svn_remote[@]} + 1))]="$value" + svn_remotes=${svn_remotes}${value}${LF} # URI\nURI\n... svn_url_pattern="$svn_url_pattern\\|$value" upstream_type=svn+git # default upstream type is SVN if available, else git ;; @@ -156,25 +156,37 @@ __git_ps1_show_upstream () case "$upstream_type" in git) upstream_type="@{upstream}" ;; svn*) - # get the upstream from the "git-svn-id: ..." in a commit message - # (git-svn uses essentially the same procedure internally) - local -a svn_upstream - svn_upstream=($(git log --first-parent -1 \ - --grep="^git-svn-id: \(${svn_url_pattern#??}\)" 2>/dev/null)) - if [[ 0 -ne ${#svn_upstream[@]} ]]; then - svn_upstream=${svn_upstream[${#svn_upstream[@]} - 2]} - svn_upstream=${svn_upstream%@*} - local n_stop="${#svn_remote[@]}" - for ((n=1; n <= n_stop; n++)); do - svn_upstream=${svn_upstream#${svn_remote[$n]}} - done + # successful svn-upstream resolution: + # - get the list of configured svn-remotes ($svn_remotes set above) + # - get the last commit which seems from one of our svn-remotes + # - confirm that it is from one of the svn-remotes + # - use $GIT_SVN_ID if set, else "git-svn" - if [[ -z "$svn_upstream" ]]; then + # get upstream from "git-svn-id: UPSTRM@N HASH" in a commit message + # (git-svn uses essentially the same procedure internally) + local svn_upstream="$( + git log --first-parent -1 \ + --grep="^git-svn-id: \(${svn_url_pattern#??}\)" 2>/dev/null + )" + + if [ -n "$svn_upstream" ]; then + # extract the URI, assuming --grep matched the last line + svn_upstream=${svn_upstream##*$LF} # last line + svn_upstream=${svn_upstream#*: } # UPSTRM@N HASH + svn_upstream=${svn_upstream%@*} # UPSTRM + + case ${LF}${svn_remotes} in + *"${LF}${svn_upstream}${LF}"*) + # grep indeed matched the last line - it's our remote # default branch name for checkouts with no layout: upstream_type=${GIT_SVN_ID:-git-svn} - else + ;; + *) + # the commit message includes one of our remotes, but + # it's not at the last line. is $svn_upstream junk? upstream_type=${svn_upstream#/} - fi + ;; + esac elif [[ "svn+git" = "$upstream_type" ]]; then upstream_type="@{upstream}" fi From patchwork Sat Aug 17 09:25:56 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: avih X-Patchwork-Id: 13767077 Received: from mail-wm1-f49.google.com (mail-wm1-f49.google.com [209.85.128.49]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 1AB181487DF for ; Sat, 17 Aug 2024 09:26:07 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.49 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1723886769; cv=none; b=Vm9j7iSgUjLGMj6Jl32SMn+9fo293DWRn7H70nD5GC4z7Rw4pUoDu6lJeoJiLQFiyoNPosfHKFGk7ivMfoaR4BQuBIPj/9fE/CWpxcm57NsXAIwlgyVgIQksuW+axUlzzqmEdq49Ht5EgpncffZhPv5fPLM1Hi8Rs5aJUiZJVGc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1723886769; c=relaxed/simple; bh=Y/eflf72LHbfyadXjodWb8yDEzd6vBwvAvyrlVdBjOc=; h=Message-Id:In-Reply-To:References:From:Date:Subject:Content-Type: MIME-Version:To:Cc; b=OFJVN/zDwhVRPEZb2UYzTBIDHA5puiSXBY9EtqtvRnVxbLDVXx+vhRRp5Hc+kGvk5qG4+j5VFJ0mjuJnGbsmq2PIEZG1Sz3KyFDMBPfxLMM7Ku4lQCOHWV80u1Owj0a4zU97bk3uKPEtGzlerDQJUnhAaTnNFYZWVXmdptIDKzw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=NFhXaC8e; arc=none smtp.client-ip=209.85.128.49 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="NFhXaC8e" Received: by mail-wm1-f49.google.com with SMTP id 5b1f17b1804b1-428141be2ddso19103825e9.2 for ; Sat, 17 Aug 2024 02:26:07 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1723886766; x=1724491566; darn=vger.kernel.org; h=cc:to:mime-version:content-transfer-encoding:fcc:subject:date:from :references:in-reply-to:message-id:from:to:cc:subject:date :message-id:reply-to; bh=VHG2sFf1oXdGYAQiFJCppD/TIS+KE4TS3ITpeGhcpNk=; b=NFhXaC8esb454RzhNrB7oTQM59SupDsyjtpIu+KcnUO3/xb+pc6BgE+TXzGLPOXfT1 CvmHQL6ZXZL334aPcMKxMGOgJlz2Hfeq7ioy1Jng4QAxB+uNvwz9PX31aNvDxDrLXoO2 lbd4JCpwQ7qsqFTc1c+JUX8lPtYna87spTUkkTdnrQcCx6RpFyGniUFeKGEaJ4GPg76z fBpl9nhw0HZG5ASK6HbzlunGG2u3JZf2+WVocOTTeGerbhJQzjxGg98EUxJF1K30d882 P69yaTmxw5Wug3FcI8UD4oyyXsiyMKTz1D2vu+MEKehOPKmt7f/1sQn6xZ8eXVk85g+O a/GQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1723886766; x=1724491566; h=cc:to:mime-version:content-transfer-encoding:fcc:subject:date:from :references:in-reply-to:message-id:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=VHG2sFf1oXdGYAQiFJCppD/TIS+KE4TS3ITpeGhcpNk=; b=TUq2DcRlxg6kmX6UynzOA+wVnwFaFH5EFAcQmYBIHuxxzcAVL/hVh5rDkwltr4URhW qNOGBHQGBzBmXsoHdsxGZuE6O2Zj4Pv5PGgPP9EEJIEqCB7Id9gAw++Xtp8rWg5TOGcp ZOXxPSl3ilXPdgpGqClEUGD3akEMtZBuWw8qlbGsdbSFEdRuTqbLtNuhP47y58FdDgJ7 erdpOVhyVdTmiSgHLlV1+sU6efpEQ4aMriKi+7tGHC0h3tWnbu14TLx6NqclMivCb6zB pLuV4LnordMYC3bXcdGMT+BLgZPiW45XD9RgyDMNqMSGLm1xLcEUGYkO0lTXxkXisYlO ALrQ== X-Gm-Message-State: AOJu0YwpL09pajw++OyUk18fua74zSvzBrgPCCQ3PTf6MqHB56Ro416s Ay2Sv861l5DkWHzjkPsCQpsn+6C8laL1phevXtbPp43LDy9MHm+013zhZg== X-Google-Smtp-Source: AGHT+IFRAah2Tmkok1ISyFZ2jJ+FoUB1eeVOvMps2v5x8nU11OGgOMuAVqGt5n1DhqnAm/HJCdSC3Q== X-Received: by 2002:a05:600c:3b04:b0:429:994:41a2 with SMTP id 5b1f17b1804b1-429ed785b80mr30050555e9.7.1723886765713; Sat, 17 Aug 2024 02:26:05 -0700 (PDT) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-429ded7c93esm98103425e9.41.2024.08.17.02.26.05 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 17 Aug 2024 02:26:05 -0700 (PDT) Message-Id: <232340902a1feeafe526528eb88b8d0814d11545.1723886761.git.gitgitgadget@gmail.com> In-Reply-To: References: Date: Sat, 17 Aug 2024 09:25:56 +0000 Subject: [PATCH v3 4/8] git-prompt: replace [[...]] with standard code Fcc: Sent Precedence: bulk X-Mailing-List: git@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 To: git@vger.kernel.org Cc: "Junio C. Hamano" , "brian m. carlson" , Patrick Steinhardt , Avi Halachmi , "Avi Halachmi (:avih)" From: "Avi Halachmi (:avih)" From: "Avi Halachmi (:avih)" The existing [[...]] tests were either already valid as standard [...] tests, or only required minimal retouch: Notes: - [[...]] doesn't do field splitting and glob expansion, so $var or $(cmd...) don't need quoting, but [... does need quotes. - [[ X == Y ]] when Y is a string is same as [ X = Y ], but if Y is a pattern, then we need: case X in Y)... ; esac . - [[ ... && ... ]] was replaced with [ ... ] && [ ... ] . - [[ -o ]] requires [[...]], so put it in "eval" and only eval it in zsh, so other shells would not abort on syntax error (posix says [[ has unspecified results, shells allowed to reject it) - ((x++)) was changed into x=$((x+1)) (yeah, not [[...]] ...) Shells which accepted the previous forms: - bash, zsh, ksh93, mksh, openbsd sh, pdksh. Shells which didn't, and now can process it: - dash, free/net bsd sh, busybox-ash, Schily Bourne sh, yash. Signed-off-by: Avi Halachmi (:avih) --- contrib/completion/git-prompt.sh | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/contrib/completion/git-prompt.sh b/contrib/completion/git-prompt.sh index 75c3a813fda..4781261f868 100644 --- a/contrib/completion/git-prompt.sh +++ b/contrib/completion/git-prompt.sh @@ -126,7 +126,7 @@ __git_ps1_show_upstream () case "$key" in bash.showupstream) GIT_PS1_SHOWUPSTREAM="$value" - if [[ -z "${GIT_PS1_SHOWUPSTREAM}" ]]; then + if [ -z "${GIT_PS1_SHOWUPSTREAM}" ]; then p="" return fi @@ -187,14 +187,14 @@ __git_ps1_show_upstream () upstream_type=${svn_upstream#/} ;; esac - elif [[ "svn+git" = "$upstream_type" ]]; then + elif [ "svn+git" = "$upstream_type" ]; then upstream_type="@{upstream}" fi ;; esac # Find how many commits we are ahead/behind our upstream - if [[ -z "$legacy" ]]; then + if [ -z "$legacy" ]; then count="$(git rev-list --count --left-right \ "$upstream_type"...HEAD 2>/dev/null)" else @@ -206,8 +206,8 @@ __git_ps1_show_upstream () for commit in $commits do case "$commit" in - "<"*) ((behind++)) ;; - *) ((ahead++)) ;; + "<"*) behind=$((behind+1)) ;; + *) ahead=$((ahead+1)) ;; esac done count="$behind $ahead" @@ -217,7 +217,7 @@ __git_ps1_show_upstream () fi # calculate the result - if [[ -z "$verbose" ]]; then + if [ -z "$verbose" ]; then case "$count" in "") # no upstream p="" ;; @@ -243,7 +243,7 @@ __git_ps1_show_upstream () *) # diverged from upstream upstream="|u+${count#* }-${count% *}" ;; esac - if [[ -n "$count" && -n "$name" ]]; then + if [ -n "$count" ] && [ -n "$name" ]; then __git_ps1_upstream_name=$(git rev-parse \ --abbrev-ref "$upstream_type" 2>/dev/null) if [ $pcmode = yes ] && [ $ps1_expanded = yes ]; then @@ -265,7 +265,7 @@ __git_ps1_show_upstream () # their own color. __git_ps1_colorize_gitstring () { - if [[ -n ${ZSH_VERSION-} ]]; then + if [ -n "${ZSH_VERSION-}" ]; then local c_red='%F{red}' local c_green='%F{green}' local c_lblue='%F{blue}' @@ -417,7 +417,7 @@ __git_ps1 () # incorrect.) # local ps1_expanded=yes - [ -z "${ZSH_VERSION-}" ] || [[ -o PROMPT_SUBST ]] || ps1_expanded=no + [ -z "${ZSH_VERSION-}" ] || eval '[[ -o PROMPT_SUBST ]]' || ps1_expanded=no [ -z "${BASH_VERSION-}" ] || shopt -q promptvars || ps1_expanded=no local repo_info rev_parse_exit_code @@ -502,11 +502,13 @@ __git_ps1 () return $exit fi - if [[ $head == "ref: "* ]]; then + case $head in + "ref: "*) head="${head#ref: }" - else + ;; + *) head="" - fi + esac ;; *) head="$(git symbolic-ref HEAD 2>/dev/null)" @@ -542,8 +544,8 @@ __git_ps1 () fi local conflict="" # state indicator for unresolved conflicts - if [[ "${GIT_PS1_SHOWCONFLICTSTATE-}" == "yes" ]] && - [[ $(git ls-files --unmerged 2>/dev/null) ]]; then + if [ "${GIT_PS1_SHOWCONFLICTSTATE-}" = "yes" ] && + [ "$(git ls-files --unmerged 2>/dev/null)" ]; then conflict="|CONFLICT" fi From patchwork Sat Aug 17 09:25:57 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: avih X-Patchwork-Id: 13767078 Received: from mail-wm1-f43.google.com (mail-wm1-f43.google.com [209.85.128.43]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id DE3861494CA for ; Sat, 17 Aug 2024 09:26:08 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.43 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1723886770; cv=none; b=QhzkT45s131KbPbjhj43dHsylBPIBIV7azphbs+KjCOT10ZQ5eDkf+MbX7G4ZKp2SWSFO5/9ORCRJvErZUtYy7Yx4ZbnCKLwFJ9DjiAMxb9K/7GXy4spQjMWWXXCZXCdc0zn8ETGMQ95LndvaTazb+ZCxdobhbzMznqhRYlskmg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1723886770; c=relaxed/simple; bh=BZjBHRo4bHeEbZgXGYTVySCua1tJEJ5xPDv5RKUpfSY=; h=Message-Id:In-Reply-To:References:From:Date:Subject:Content-Type: MIME-Version:To:Cc; b=JHRf2BlygB3+g9jWPZQXwrQtLpKRAvsPMwuUiMrQDZcSAFWhb3WPIDKot6sXiYPkenwI4gNOR39PXTFMxx9CfJH+ZNyjWdbPOoGSkrIBKJnQFLW5LduhNBucZWoKXSdp/qZgtSL3xIcCH+0VGvrlPWKuzz1RblYgeGcxExErcJo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=YMVr6v9U; arc=none smtp.client-ip=209.85.128.43 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="YMVr6v9U" Received: by mail-wm1-f43.google.com with SMTP id 5b1f17b1804b1-4280bca3960so21968695e9.3 for ; Sat, 17 Aug 2024 02:26:08 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1723886767; x=1724491567; darn=vger.kernel.org; h=cc:to:mime-version:content-transfer-encoding:fcc:subject:date:from :references:in-reply-to:message-id:from:to:cc:subject:date :message-id:reply-to; bh=uXQtFgPK3AykP0783VzfOfBQFy/XbiiPbTi7bjgCCiU=; b=YMVr6v9UZXNseHEDG1umQh/NwmBDLUBj2MQPXlPREGKInCaUMyrv72yjGXOdWyIEl2 eN2dhwndz0pY+tmtvyODlMV7am0m1Goff+iF5E/6sMtIM49p1KlEzn4JNkMwYSyGz7qT daX+HAVe814Axp1efevpT486thuSSGYKcBbGtMBlcfA+i53lvi+i0jBkKySA7gxzBXYT q7Brg8CyXOSvxHL5JaTWVfAdKWHlXGEYJzo5kQCRTSMIxiXHujjmi/Xmb53+xWBJbALd teJ2wxUBaoUypAfNysY9Yc+zM23Way8kDF3a4XrjtOE18fjhMvT7wW3AQfHiKLprBdLk 8xHg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1723886767; x=1724491567; h=cc:to:mime-version:content-transfer-encoding:fcc:subject:date:from :references:in-reply-to:message-id:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=uXQtFgPK3AykP0783VzfOfBQFy/XbiiPbTi7bjgCCiU=; b=O1dVcv12kl5s3z/vPo3bwpxmSj3Z/NNCVUhi9haHthJguzFC9QVvE+qPxQYFKu6SZQ RP/t0jD+aAfBHjuFq73bE0BSYe0ycQTsh+H0JnMJHpK+bmRA7/oxJCaMCWaNtUjM/4NF jdYCs9XpzCTQ1Wm8rtxtnY8bl1o3ZxXCgvFhsZPNhwFwg5E/cHYjj28KQuH98za1nW9R vmGBDVoW/4mmYCXn8f4M6+njZZMQ7ZrtWfU+NqXpWX/zCGQ7TnHNQz+ANf7ByPD3LAC8 zovmA73LFCXykzhPp+UIgRmLOAeLNZgJssCKdHPDdHtYjy7/o9+NqgbuGobtFTqxwPOY rmpQ== X-Gm-Message-State: AOJu0YwOFQwUMrDdIBpL81Zja4BZ2pjLk/CoE44w+ujj1NOCutm0YBhZ RdFBq4ZCcN1Kgc2hYdZWfajJiZsm6h8CnS4RcvEtkXMATCKef/CC0sZ3dA== X-Google-Smtp-Source: AGHT+IETy8Wg6r4eSOikWf0CDGHPn2IYxJ04CxMUg9dVaiJaVOvQCa3ZQaF9WUeqggCbe5lbXNYZDg== X-Received: by 2002:a05:600c:5844:b0:42a:a6d2:328b with SMTP id 5b1f17b1804b1-42aa6d233eemr18003315e9.30.1723886766516; Sat, 17 Aug 2024 02:26:06 -0700 (PDT) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-429ded7d5bfsm100405185e9.46.2024.08.17.02.26.06 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 17 Aug 2024 02:26:06 -0700 (PDT) Message-Id: <3a41ad889cc33a1fc0414b8f14af6438b49c88ee.1723886761.git.gitgitgadget@gmail.com> In-Reply-To: References: Date: Sat, 17 Aug 2024 09:25:57 +0000 Subject: [PATCH v3 5/8] git-prompt: add some missing quotes Fcc: Sent Precedence: bulk X-Mailing-List: git@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 To: git@vger.kernel.org Cc: "Junio C. Hamano" , "brian m. carlson" , Patrick Steinhardt , Avi Halachmi , "Avi Halachmi (:avih)" From: "Avi Halachmi (:avih)" From: "Avi Halachmi (:avih)" The issues which this commit fixes are unlikely to be broken in real life, but the fixes improve correctness, and would prevent bugs in some uncommon cases, such as weird IFS values. Listing some portability guideline here for future reference. I'm leaving it to someone else to decide whether to include it in the file itself, place is as a new file, or not. --------- The command "local" is non standard, but is allowed in this file: - Quote initialization if it can expand (local x="$y"). See below. - Don't assume initial value after "local x". Either initialize it (local x=..), or set before first use (local x;.. x=..; ). (between shells, "local x" can unset x, or inherit it, or do x= ) Other non-standard features beyond "local" are to be avoided. Use the standard "test" - [...] instead of non-standard [[...]] . -------- Quotes (some portability things, but mainly general correctness): Quotes prevent tilde-expansion of some unquoted literal tildes (~). If the expansion is undesirable, quotes would ensure that. Tilds expanded: a=~user:~/ ; echo ~user ~/dir not expanded: t="~"; a=${t}user b=\~foo~; echo "~user" $t/dir But the main reason for quoting is to prevent IFS field splitting (which also coalesces IFS chars) and glob expansion in parts which contain parameter/arithmetic expansion or command substitution. "Simple command" (POSIX term) is assignment[s] and/or command [args]. Examples: foo=bar # one assignment foo=$bar x=y # two assignments foo bar # command, no assignments x=123 foo bar # one assignment and a command The assignments part is not IFS-split or glob-expanded. The command+args part does get IFS field split and glob expanded, but only at unquoted expanded/substituted parts. In the command+args part, expanded/substituted values must be quoted. (the commands here are "[" and "local"): Good: [ "$mode" = yes ]; local s="*" x="$y" e="$?" z="$(cmd ...)" Bad: [ $mode = yes ]; local s=* x=$y e=$? z=$(cmd...) The arguments to "local" do look like assignments, but they're not the assignment part of a simple command. they're at the command part. Still at the command part, no need to quote non-expandable values: Good: local x= y=yes; echo OK OK, but not required: local x="" y="yes"; echo "OK" But completely empty (NULL) arguments must be quoted: foo "" is not the same as: foo Assignments in simple commands - with or without an actual command, don't need quoting becase there's no IFS split or glob expansion: Good: s=* a=$b c=$(cmd...)${x# foo }${y- } [cmd ...] It's also OK to use double quotes, but not required. This behavior (no IFS/glob) is called "assignment context", and "local" does not behave with assignment context in some shells, hence we require quotes when using "local" - for compatibility. The value between 'case' and 'in' doesn't IFS-split/glob-expand: Good: case * $foo $(cmd...) in ... ; esac identical: case "* $foo $(cmd...)" in ... ; esac Nested quotes in command substitution are fine, often necessary: Good: echo "$(foo... "$x" "$(bar ...)")" Nested quotes in substring ops are legal, and sometimes needed to prevent interpretation as a pattern, but not the most readable: Legal: foo "${x#*"$y" }" Nested quotes in "maybe other value" subst are invalid, unnecessary: Good: local x="${y- }"; foo "${z:+ $a }" Bad: local x="${y-" "}"; foo "${z:+" $a "}" Outer/inner quotes in "maybe other value" have different use cases: "${x-$y}" always one quoted arg: "$x" if x is set, else "$y". ${x+"$x"} one quoted arg "$x" if x is set, else no arg at all. Unquoted $x is similar to the second case, but it would get split into few arguments if it includes any of the IFS chars. Assignments don't need the outer quotes, and the braces delimit the value, so nested quotes can be avoided, for readability: a=$(foo "$x") a=${x#*"$y" } c=${y- }; bar "$a" "$b" "$c" Signed-off-by: Avi Halachmi (:avih) --- contrib/completion/git-prompt.sh | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/contrib/completion/git-prompt.sh b/contrib/completion/git-prompt.sh index 4781261f868..5d7f236fe48 100644 --- a/contrib/completion/git-prompt.sh +++ b/contrib/completion/git-prompt.sh @@ -246,7 +246,7 @@ __git_ps1_show_upstream () if [ -n "$count" ] && [ -n "$name" ]; then __git_ps1_upstream_name=$(git rev-parse \ --abbrev-ref "$upstream_type" 2>/dev/null) - if [ $pcmode = yes ] && [ $ps1_expanded = yes ]; then + if [ "$pcmode" = yes ] && [ "$ps1_expanded" = yes ]; then upstream="$upstream \${__git_ps1_upstream_name}" else upstream="$upstream ${__git_ps1_upstream_name}" @@ -278,12 +278,12 @@ __git_ps1_colorize_gitstring () local c_lblue=$'\001\e[1;34m\002' local c_clear=$'\001\e[0m\002' fi - local bad_color=$c_red - local ok_color=$c_green + local bad_color="$c_red" + local ok_color="$c_green" local flags_color="$c_lblue" local branch_color="" - if [ $detached = no ]; then + if [ "$detached" = no ]; then branch_color="$ok_color" else branch_color="$bad_color" @@ -360,7 +360,7 @@ __git_sequencer_status () __git_ps1 () { # preserve exit status - local exit=$? + local exit="$?" local pcmode=no local detached=no local ps1pc_start='\u@\h:\w ' @@ -379,7 +379,7 @@ __git_ps1 () ;; 0|1) printf_format="${1:-$printf_format}" ;; - *) return $exit + *) return "$exit" ;; esac @@ -427,7 +427,7 @@ __git_ps1 () rev_parse_exit_code="$?" if [ -z "$repo_info" ]; then - return $exit + return "$exit" fi local short_sha="" @@ -449,7 +449,7 @@ __git_ps1 () [ "$(git config --bool bash.hideIfPwdIgnored)" != "false" ] && git check-ignore -q . then - return $exit + return "$exit" fi local sparse="" @@ -499,7 +499,7 @@ __git_ps1 () case "$ref_format" in files) if ! __git_eread "$g/HEAD" head; then - return $exit + return "$exit" fi case $head in @@ -597,10 +597,10 @@ __git_ps1 () fi fi - local z="${GIT_PS1_STATESEPARATOR-" "}" + local z="${GIT_PS1_STATESEPARATOR- }" b=${b##refs/heads/} - if [ $pcmode = yes ] && [ $ps1_expanded = yes ]; then + if [ "$pcmode" = yes ] && [ "$ps1_expanded" = yes ]; then __git_ps1_branch_name=$b b="\${__git_ps1_branch_name}" fi @@ -612,7 +612,7 @@ __git_ps1 () local f="$h$w$i$s$u$p" local gitstring="$c$b${f:+$z$f}${sparse}$r${upstream}${conflict}" - if [ $pcmode = yes ]; then + if [ "$pcmode" = yes ]; then if [ "${__git_printf_supports_v-}" != yes ]; then gitstring=$(printf -- "$printf_format" "$gitstring") else @@ -623,5 +623,5 @@ __git_ps1 () printf -- "$printf_format" "$gitstring" fi - return $exit + return "$exit" } From patchwork Sat Aug 17 09:25:58 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: avih X-Patchwork-Id: 13767079 Received: from mail-wr1-f41.google.com (mail-wr1-f41.google.com [209.85.221.41]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A729B1487ED for ; Sat, 17 Aug 2024 09:26:09 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.41 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1723886771; cv=none; b=SxZLaQL8+8i4rT48/nvmzGstEDM+adfR4SY7c6k2wMyB0dCbf2b6mT1KWD6e8NRekQEXETWf9Of1C/JSYcJHc+kiqL9Y9mUGvvStePrF2hwgRfbUjk9yY9gZkA8AF2P+A9RvtEVoXYpfZgH4BJGX8W0ABib7OObMDnTXiaNMKgo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1723886771; c=relaxed/simple; bh=+OzamXJet4poQcDjfbocCqRQTImWRURbURYBdomHj0o=; h=Message-Id:In-Reply-To:References:From:Date:Subject:Content-Type: MIME-Version:To:Cc; b=PRplpUz8/7MNC8dKPxa60yvhpfX+Tflkjtk6lzGKl5zH0l1mCQe9ND+17EcmiYVR5cePRJSNc4NGlmKuDOcDLHDRrSjqxdPCIA9/XZqN9PYIWqWWCnugXTKZ9fCQVg1WEzu+MuLLWbq/4gNysz9bRi64TzmaBNY37L3sW6K5Nc8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=F/jF8m8D; arc=none smtp.client-ip=209.85.221.41 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="F/jF8m8D" Received: by mail-wr1-f41.google.com with SMTP id ffacd0b85a97d-371aa511609so164602f8f.1 for ; Sat, 17 Aug 2024 02:26:09 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1723886767; x=1724491567; darn=vger.kernel.org; h=cc:to:mime-version:content-transfer-encoding:fcc:subject:date:from :references:in-reply-to:message-id:from:to:cc:subject:date :message-id:reply-to; bh=QUEdTvj/rTiuXZmr7VJNrLRqDEkcl3gCFHL3SGDS+Mc=; b=F/jF8m8DU3LrmYT0u3UYylFuwdoRlw0vRzqvfu1YvWXetzOFJRRDjNB1V1dsbqbs0u FaWw120CcVbfe5tvHt2ViJ+Pso5KFNMS1e0yLd4gvuIpBGdLj+vbkWw9D9SFa3P0xSTL JIHGbllTKzAuhucWHuG/vlikkhkey5uqGft+/twxovEXqx/ebC3gLfhUiQfrWZyk4aHd e9jCAsu3ldbocr9NLlGpzjDhQT6TsZ2wfIf45oX+Xmv7v9ynYzALdDGCSvoymXs1IlEx AIJyAeIktkVWQiVGuj1xu386qKYUHwHAeBpkCyElWWu0y4LL13pKeo1rHil0wEiyKnHI oonw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1723886767; x=1724491567; h=cc:to:mime-version:content-transfer-encoding:fcc:subject:date:from :references:in-reply-to:message-id:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=QUEdTvj/rTiuXZmr7VJNrLRqDEkcl3gCFHL3SGDS+Mc=; b=qq1EpsxfSDZFQ/33uupr+AUGxJB0eE0/2jcqWYX+yzBpu28kG/UuzgRadN65W98elv H4ExiBW0Tp/OjWeo5HAFXIq3TePbkMVHyXyPrkNLcu78jvAUnCJSlERLuHoCffYQk2RK p7AvaKKyG6gGgD/urvTek7j6T6qF1erBn4CYoGSTxryjqR4385VsTXLmxpX96dWmKxPq f/9MnaigkUgQwRgTMnKSD+gBrmlHwHPJSb7gYlJD9916+T/tpjnaCesNllU7jMlXCIAw /CduTlGkmV4tmTb1lKuikmHRbwvo7W40IO6IQkcfr1zIaI2C/Mvy9+mrFmb5YN1/SXEo DzSw== X-Gm-Message-State: AOJu0YxcDWSNRfiA3AgGLjsVMo0vBOxc/6ef4Ytkfwf66y97jBDi138o Zj4+NZ/w3iBt3EW6EzzJndAwG+qpanLiA1nBF0LOm50r0mH281Om5DnlTA== X-Google-Smtp-Source: AGHT+IHTqDLMibpIAvbzsj3oI1OL7vII/GhnySp/Jk1wRhEsW6KyUo9FDTduyikB9Y4FBkyx4KGuxA== X-Received: by 2002:adf:a29c:0:b0:371:8e91:77dc with SMTP id ffacd0b85a97d-371946dcc52mr3116902f8f.63.1723886767248; Sat, 17 Aug 2024 02:26:07 -0700 (PDT) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-3718983a2eesm5455161f8f.19.2024.08.17.02.26.06 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 17 Aug 2024 02:26:06 -0700 (PDT) Message-Id: In-Reply-To: References: Date: Sat, 17 Aug 2024 09:25:58 +0000 Subject: [PATCH v3 6/8] git-prompt: don't use shell $'...' Fcc: Sent Precedence: bulk X-Mailing-List: git@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 To: git@vger.kernel.org Cc: "Junio C. Hamano" , "brian m. carlson" , Patrick Steinhardt , Avi Halachmi , "Avi Halachmi (:avih)" From: "Avi Halachmi (:avih)" From: "Avi Halachmi (:avih)" $'...' is new in POSIX (2024), and some shells support it in recent versions, while others have had it for decades (bash, zsh, ksh93). However, there are still enough shells which don't support it, and it's cheap to use an alternative form which works in all shells, so let's do that instead of dismissing it as "it's compliant". It was agreed to use one form rather than $'...' where supported and fallback otherwise. shells where $'...' works: - bash, zsh, ksh93, mksh, busybox-ash, dash master, free/net bsd sh. shells where it doesn't work, but the new fallback works: - all dash releases (up to 0.5.12), older versions of free/net bsd sh, openbsd sh, pdksh, all Schily Bourne sh variants, yash. Signed-off-by: Avi Halachmi (:avih) --- contrib/completion/git-prompt.sh | 47 ++++++++++++++++++++------------ 1 file changed, 29 insertions(+), 18 deletions(-) diff --git a/contrib/completion/git-prompt.sh b/contrib/completion/git-prompt.sh index 5d7f236fe48..c3dd38f847c 100644 --- a/contrib/completion/git-prompt.sh +++ b/contrib/completion/git-prompt.sh @@ -111,6 +111,12 @@ __git_printf_supports_v= printf -v __git_printf_supports_v -- '%s' yes >/dev/null 2>&1 +# like __git_SOH=$'\001' etc but works also in shells without $'...' +eval "$(printf ' + __git_SOH="\001" __git_STX="\002" __git_ESC="\033" + __git_LF="\n" __git_CRLF="\r\n" +')" + # stores the divergence from upstream in $p # used by GIT_PS1_SHOWUPSTREAM __git_ps1_show_upstream () @@ -118,7 +124,7 @@ __git_ps1_show_upstream () local key value local svn_remotes="" svn_url_pattern="" count n local upstream_type=git legacy="" verbose="" name="" - local LF=$'\n' + local LF="$__git_LF" # get some config options from git-config local output="$(git config -z --get-regexp '^(svn-remote\..*\.url|bash\.showupstream)$' 2>/dev/null | tr '\0\n' '\n ')" @@ -271,12 +277,16 @@ __git_ps1_colorize_gitstring () local c_lblue='%F{blue}' local c_clear='%f' else - # Using \001 and \002 around colors is necessary to prevent - # issues with command line editing/browsing/completion! - local c_red=$'\001\e[31m\002' - local c_green=$'\001\e[32m\002' - local c_lblue=$'\001\e[1;34m\002' - local c_clear=$'\001\e[0m\002' + # \001 (SOH) and \002 (STX) are 0-width substring markers + # which bash/readline identify while calculating the prompt + # on-screen width - to exclude 0-screen-width esc sequences. + local c_pre="${__git_SOH}${__git_ESC}[" + local c_post="m${__git_STX}" + + local c_red="${c_pre}31${c_post}" + local c_green="${c_pre}32${c_post}" + local c_lblue="${c_pre}1;34${c_post}" + local c_clear="${c_pre}0${c_post}" fi local bad_color="$c_red" local ok_color="$c_green" @@ -312,7 +322,7 @@ __git_ps1_colorize_gitstring () # variable, in that order. __git_eread () { - test -r "$1" && IFS=$'\r\n' read -r "$2" <"$1" + test -r "$1" && IFS=$__git_CRLF read -r "$2" <"$1" } # see if a cherry-pick or revert is in progress, if the user has committed a @@ -430,19 +440,20 @@ __git_ps1 () return "$exit" fi + local LF="$__git_LF" local short_sha="" if [ "$rev_parse_exit_code" = "0" ]; then - short_sha="${repo_info##*$'\n'}" - repo_info="${repo_info%$'\n'*}" + short_sha="${repo_info##*$LF}" + repo_info="${repo_info%$LF*}" fi - local ref_format="${repo_info##*$'\n'}" - repo_info="${repo_info%$'\n'*}" - local inside_worktree="${repo_info##*$'\n'}" - repo_info="${repo_info%$'\n'*}" - local bare_repo="${repo_info##*$'\n'}" - repo_info="${repo_info%$'\n'*}" - local inside_gitdir="${repo_info##*$'\n'}" - local g="${repo_info%$'\n'*}" + local ref_format="${repo_info##*$LF}" + repo_info="${repo_info%$LF*}" + local inside_worktree="${repo_info##*$LF}" + repo_info="${repo_info%$LF*}" + local bare_repo="${repo_info##*$LF}" + repo_info="${repo_info%$LF*}" + local inside_gitdir="${repo_info##*$LF}" + local g="${repo_info%$LF*}" if [ "true" = "$inside_worktree" ] && [ -n "${GIT_PS1_HIDE_IF_PWD_IGNORED-}" ] && From patchwork Sat Aug 17 09:25:59 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: avih X-Patchwork-Id: 13767080 Received: from mail-wm1-f50.google.com (mail-wm1-f50.google.com [209.85.128.50]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 53C37149DFA for ; Sat, 17 Aug 2024 09:26:10 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.50 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1723886772; cv=none; b=VdbJ7hkmIuZRaR6jkAEGjZHME1i61pw5DWQlygdNkRNzDfIFy0S2K+VYxsf4o3AdiobenBAAnERLxNcjBWKa0clBUxdhGqqUA+KpSao5uVgc+7iNYJrNFDd6m50jhJBOahoWOkcM3y6lDf6Q9D9h44KILjZaIN6fIwxO1z7uQq0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1723886772; c=relaxed/simple; bh=Y2btUPlnWF9x450ZcUCJVsOoWZUW+2KGM+sT5G0fyQ4=; h=Message-Id:In-Reply-To:References:From:Date:Subject:Content-Type: MIME-Version:To:Cc; b=jD+3P6UkVtU1FLggD4AlLCGiCQQuCWslSRkBw3OazH+nm77lfDTGiSeSz8oh7spF9OdDlMPprgP+pxCfd106tEv3uR5zBB0PbDz6falttKGs0lA8PQKZv5Up05OPXLi3r9TEzw3BuL2Hj9ohtdBPRwjhnCjyLzlsDuN16jAEOvQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=SYwWlon+; arc=none smtp.client-ip=209.85.128.50 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="SYwWlon+" Received: by mail-wm1-f50.google.com with SMTP id 5b1f17b1804b1-42803bbf842so28037635e9.1 for ; Sat, 17 Aug 2024 02:26:09 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1723886768; x=1724491568; darn=vger.kernel.org; h=cc:to:mime-version:content-transfer-encoding:fcc:subject:date:from :references:in-reply-to:message-id:from:to:cc:subject:date :message-id:reply-to; bh=59NEmS/bFLhtsv9T4v3SS4TYomtN8k2v3x2e1iHe8Q8=; b=SYwWlon+LvwjZ7hhTL2xw0e1TRQmTOAaTZ8egi2T0rxvpGUlLAkdw8qfkrbFcbXZRW WecgtxfmDzTfJBfeByt30vqydUooeR1wYAzLWoPBiCqksmIeKmRPU/WtNXIuzbXUHmsb PS9J84IJAfVc3pvonCK39AJIdVD/jYPvlYK2JjpjU+Q8FLDWd1u6pjwniDUyS1IgGVJ/ NC6GS0qy+BI8xJ6VD37lMJIdGk9tylFXlTSgfQwHGZwqCllqHUCgsZeBoYgpb7kvpbPJ Q/NQm+OA39uH7E2EFu1T9AqcOAFYZsAncsI+3oWBDUegmmLKK9mxRB0ZM3plMzk0lU94 b36Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1723886768; x=1724491568; h=cc:to:mime-version:content-transfer-encoding:fcc:subject:date:from :references:in-reply-to:message-id:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=59NEmS/bFLhtsv9T4v3SS4TYomtN8k2v3x2e1iHe8Q8=; b=N+pcs9buGIdZnRFxnGmH2bEthh3i8fpGI4bZdXZg4AQGimCgvVnmbcQcs6dBgcGEkW reYh8TCSsOKHG2w6Ac8yH205kTAVV+tS07Dr4emItV2L6UNcwtLt+ESAD8Wc5rkB9/vZ pbYFWZA0HcyrY1Pl2fiPvyhKkrepDc/C/NpfZkpx+b8DfTwht/hBu4OEK4Nf4AvS8FE0 MEdetlpLrVZiQpJBe3TP2HfeN2FyOIEwgdpSngQ0vfz+HEadTp3gjGQQmA6Lya9hqreR ptYx7CQlXd9CGZhAb0pcvslxWTatg2INVWNzfNliIXfgqHvmEjEtnzL587Bbj0fFbRo7 fGjg== X-Gm-Message-State: AOJu0YwtPLGNMxGjFpiPTe7Xek9/Lf8v8Rc7MKohtMae/8J3ivSYXSDe QZtd2PiOTLGhKGsQn80YASI3eds60wO+hdwPXY3ZwnZYoD6Ds2v6ZqijhQ== X-Google-Smtp-Source: AGHT+IHfJxhPzDfWrwGhKmrZbp9iFrmkkCU1+skGfTvHnm0ePYnmEYYkqjseYt10L6X9bsQBfHWsMA== X-Received: by 2002:a05:600c:3104:b0:426:6ee7:d594 with SMTP id 5b1f17b1804b1-429ed784076mr39524165e9.7.1723886767982; Sat, 17 Aug 2024 02:26:07 -0700 (PDT) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-429ded285easm97942245e9.11.2024.08.17.02.26.07 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 17 Aug 2024 02:26:07 -0700 (PDT) Message-Id: In-Reply-To: References: Date: Sat, 17 Aug 2024 09:25:59 +0000 Subject: [PATCH v3 7/8] git-prompt: ta-da! document usage in other shells Fcc: Sent Precedence: bulk X-Mailing-List: git@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 To: git@vger.kernel.org Cc: "Junio C. Hamano" , "brian m. carlson" , Patrick Steinhardt , Avi Halachmi , "Avi Halachmi (:avih)" From: "Avi Halachmi (:avih)" From: "Avi Halachmi (:avih)" With one big exception, git-prompt.sh should now be both almost posix compliant, and also compatible with most (posix-ish) shells. That exception is the use of "local" vars in functions, which happens extensively in the current code, and is not simple to replace with posix compliant code (but also not impossible). Luckily, almost all shells support "local" as used by the current code, with the notable exception of ksh93[u+m], but also the Schily minimal posix sh (pbosh), and yash in posix mode. See assessment below that "local" is likely the only blocker in those. So except mainly ksh93, git-prompt.sh now works in most shells: - bash, zsh, dash since at least 0.5.8, free/net bsd sh, busybox-ash, mksh, openbsd sh, pdksh(!), Schily extended Bourne sh (bosh), yash. which is quite nice. As an anecdote, replacing the 1st line in __git_ps1() (local exit=$?) with these 2 makes it work in all tested shells, even without "local": # handles only 0/1 args for simplicity. needs +5 LOC for any $# __git_e=$?; local exit="$__git_e" 2>/dev/null || {(eval 'local() { export "$@"; }'; __git_ps1 "$@"); return "$__git_e"; } Explanation: If the shell doesn't have the command "local", define our own function "local" which instead does plain (global) assignents. Then use __git_ps1 in a subshell to not clober the caller's vars. This happens to work because currently there are no name conflicts (shadow) at the code, initial value is not assumed (i.e. always doing either 'local x=...' or 'local x;... x=...'), and assigned initial values are quoted (local x="$y"), preventing word split and glob expansion (i.e. assignment context is not assumed). The last two (always init, quote values) seem to be enough to use "local" portably if supported, and otherwise shells indeed differ. Uses "eval", else shells with "local" may reject it during parsing. We don't need "export", but it's smaller than writing our own loop. While cute, this approach is not really sustainable because all the vars become global, which is hard to maintain without conflicts (but hey, it currently has no conflicts - without even trying...). However, regardless of being an anecdote, it provides some support to the assessment that "local" is the only blocker in those shells. Signed-off-by: Avi Halachmi (:avih) --- contrib/completion/git-prompt.sh | 33 ++++++++++++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/contrib/completion/git-prompt.sh b/contrib/completion/git-prompt.sh index c3dd38f847c..6be2f1dd901 100644 --- a/contrib/completion/git-prompt.sh +++ b/contrib/completion/git-prompt.sh @@ -8,8 +8,8 @@ # To enable: # # 1) Copy this file to somewhere (e.g. ~/.git-prompt.sh). -# 2) Add the following line to your .bashrc/.zshrc: -# source ~/.git-prompt.sh +# 2) Add the following line to your .bashrc/.zshrc/.profile: +# . ~/.git-prompt.sh # dot path/to/this-file # 3a) Change your PS1 to call __git_ps1 as # command-substitution: # Bash: PS1='[\u@\h \W$(__git_ps1 " (%s)")]\$ ' @@ -30,6 +30,8 @@ # Optionally, you can supply a third argument with a printf # format string to finetune the output of the branch status # +# See notes below about compatibility with other shells. +# # The repository status will be displayed only if you are currently in a # git repository. The %s token is the placeholder for the shown status. # @@ -106,6 +108,33 @@ # directory is set up to be ignored by git, then set # GIT_PS1_HIDE_IF_PWD_IGNORED to a nonempty value. Override this on the # repository level by setting bash.hideIfPwdIgnored to "false". +# +# Compatibility with other shells (beyond bash/zsh): +# +# We require posix-ish shell plus "local" support, which is most +# shells (even pdksh), but excluding ksh93 (because no "local"). +# +# Prompt integration might differ between shells, but the gist is +# to load it once on shell init with '. path/to/git-prompt.sh', +# set GIT_PS1* vars once as needed, and either place $(__git_ps1..) +# inside PS1 once (0/1 args), or, before each prompt is displayed, +# call __git_ps1 (2/3 args) which sets PS1 with the status embedded. +# +# Many shells support the 1st method of command substitution, +# though some might need to first enable cmd substitution in PS1. +# +# When using colors, each escape sequence is wrapped between byte +# values 1 and 2 (control chars SOH, STX, respectively), which are +# invisible at the output, but for bash/readline they mark 0-width +# strings (SGR color sequences) when calculating the on-screen +# prompt width, to maintain correct input editing at the prompt. +# +# Currently there's no support for different markers, so if editing +# behaves weird when using colors in __git_ps1, then the solution +# is either to disable colors, or, in some shells which only care +# about the width of the last prompt line (e.g. busybox-ash), +# ensure the git output is not at the last line, maybe like so: +# PS1='\n\w \u@\h$(__git_ps1 " (%s)")\n\$ ' # check whether printf supports -v __git_printf_supports_v= From patchwork Sat Aug 17 09:26:00 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: avih X-Patchwork-Id: 13767081 Received: from mail-wm1-f42.google.com (mail-wm1-f42.google.com [209.85.128.42]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4320D14A4E1 for ; Sat, 17 Aug 2024 09:26:11 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.42 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1723886772; cv=none; b=imr4WtPeSt+LTXNEkh27c6OH/Fy59CJYnS6gwicma6czJWRQ8FBBkZNIInJ2HdfKp9I0TKZGOw7BtZYu/EiA9ALWKQGIlWZUDkOGQuWr6GMSQ7DrLGjDR6aonQpAsfNcU5cYF7pl/WwSZ47TWta8K51o4j12VCX7vj0Tz6zbYvo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1723886772; c=relaxed/simple; bh=04M2SA6KLr1ytY4c4zDyaG6UDDk0NJk+zVZ7zJ5EVPg=; h=Message-Id:In-Reply-To:References:From:Date:Subject:Content-Type: MIME-Version:To:Cc; b=AkgV8x9KkbB6TNqJO31R2l9+HOTIxRsADTw53MsmoSc5Rdz1c0CCh7IlEGcBZ5ZqPkkoHy3JeRGe/Mcp497+msfqF2RGqfoE+bB9GZlNXVAFo0QGrtUDMNQdD0CeWQSGNe0ireJFaT217JQE7zv92N3aoSyRiqlsTNgkjcWOPNs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=a53SmrWo; arc=none smtp.client-ip=209.85.128.42 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="a53SmrWo" Received: by mail-wm1-f42.google.com with SMTP id 5b1f17b1804b1-4281faefea9so19401695e9.2 for ; Sat, 17 Aug 2024 02:26:11 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1723886769; x=1724491569; darn=vger.kernel.org; h=cc:to:mime-version:content-transfer-encoding:fcc:subject:date:from :references:in-reply-to:message-id:from:to:cc:subject:date :message-id:reply-to; bh=2u/SlEvxWfmaS8KDcb/mxNvkCVF5nerHKz183zR9kGw=; b=a53SmrWoa2RpEciH26/grbVy7LpWPHYa0d95HAIljnai5kwyLHrN8EW+O3vgPGYpCk DTw4XFq8brGdNsxPOt2dqj02LYYbtf1n3DC2HOeZs0R/uygLUfnJi9bnWz0YPOL+9qD/ BfnDJFM2859FmfVoepsGVFViFyLOxK0xlEbGiacACNDOsJaFKdo8EgdDMcU+ghC7poEV Fr9IEq1nEcZ5jPTVcT48XUMTZgYPtkeDrSpilgZqDaLjC+AMB+m+zezptkmNtJpnagoU hAF2alZbFXfX07NOhmr5fBfOQ6cq9G7b9vkg4ySLMO8p6158luzPD+IOZPJXQayx7ry8 22cg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1723886769; x=1724491569; h=cc:to:mime-version:content-transfer-encoding:fcc:subject:date:from :references:in-reply-to:message-id:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=2u/SlEvxWfmaS8KDcb/mxNvkCVF5nerHKz183zR9kGw=; b=aiw8Jn3+a7uayNFaYzXSUSMfhdLRzGZWrrgirVvgrSSJ1us7A2LyxZhzz15SyXEcF6 GgtmyhtnoSdZyDUvKKQS43Hstrm1bNPyjEKWiZoQ6r79sG24CeshXgeGVuwa7cVI4f+i eVXDKRTQ0rfuQy1ivl4Ok9EBFG5F50/yr2uAk3+M+Kw0VZVLQgxsWOAlndpmRcyFILee lUgV0oQ2L+EBm90oUswdLVlitfHqMFsOSE1S5cxqfi1hy+wBDmKngD+t/SMLTD/cu/Vl R40rUPTOTb6/LMJjIw/hKIWo1b4TpqItkzNPwJPUId0OqSxA8r9h0n5OJkKnLIxOztGl 0tSw== X-Gm-Message-State: AOJu0YyU8PQhRdRAWheVo0PouFdaw7ii0EOG5xrn1LK/m9RwQ1VkCtOB 8Bj09SpXZfHMGSOT+8h0qScI51ldoV/xo1hgkYb+LirwzQdwARV71Gaaew== X-Google-Smtp-Source: AGHT+IHkQp8FYNYI/iiz0ys0KrOZMkDozV9YIu4gNcVioA+B3690oYDd1J8X9besrKmcbE54jWaCxg== X-Received: by 2002:a05:600c:4f56:b0:426:61af:e1d6 with SMTP id 5b1f17b1804b1-429ed7cc6a7mr43099695e9.29.1723886769221; Sat, 17 Aug 2024 02:26:09 -0700 (PDT) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-429ded18468sm96982165e9.2.2024.08.17.02.26.08 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 17 Aug 2024 02:26:08 -0700 (PDT) Message-Id: <633e71a01d3b7e3e66fdca35136a837ba4975b58.1723886761.git.gitgitgadget@gmail.com> In-Reply-To: References: Date: Sat, 17 Aug 2024 09:26:00 +0000 Subject: [PATCH v3 8/8] git-prompt: support custom 0-width PS1 markers Fcc: Sent Precedence: bulk X-Mailing-List: git@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 To: git@vger.kernel.org Cc: "Junio C. Hamano" , "brian m. carlson" , Patrick Steinhardt , Avi Halachmi , "Avi Halachmi (:avih)" From: "Avi Halachmi (:avih)" From: "Avi Halachmi (:avih)" When using colors, the shell needs to identify 0-width substrings in PS1 - such as color escape sequences - when calculating the on-screen width of the prompt. Until now, we used the form %F{} in zsh - which it knows is 0-width, or otherwise use standard SGR esc sequences wrapped between byte values 1 and 2 (SOH, STX) as 0-width start/end markers, which bash/readline identify as such. But now that more shells are supported, the standard SGR sequences typically work, but the SOH/STX markers might not be identified. This commit adds support for vars GIT_PS1_COLOR_{PRE,POST} which set custom 0-width markers or disable the markers. Signed-off-by: Avi Halachmi (:avih) --- contrib/completion/git-prompt.sh | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/contrib/completion/git-prompt.sh b/contrib/completion/git-prompt.sh index 6be2f1dd901..6186c474ba7 100644 --- a/contrib/completion/git-prompt.sh +++ b/contrib/completion/git-prompt.sh @@ -129,11 +129,16 @@ # strings (SGR color sequences) when calculating the on-screen # prompt width, to maintain correct input editing at the prompt. # -# Currently there's no support for different markers, so if editing -# behaves weird when using colors in __git_ps1, then the solution -# is either to disable colors, or, in some shells which only care -# about the width of the last prompt line (e.g. busybox-ash), -# ensure the git output is not at the last line, maybe like so: +# To replace or disable the 0-width markers, set GIT_PS1_COLOR_PRE +# and GIT_PS1_COLOR_POST to other markers, or empty (nul) to not +# use markers. For instance, some shells support '\[' and '\]' as +# start/end markers in PS1 - when invoking __git_ps1 with 3/4 args, +# but it may or may not work in command substitution mode. YMMV. +# +# If the shell doesn't support 0-width markers and editing behaves +# incorrectly when using colors in __git_ps1, then, other than +# disabling color, it might be solved using multi-line prompt, +# where the git status is not at the last line, e.g.: # PS1='\n\w \u@\h$(__git_ps1 " (%s)")\n\$ ' # check whether printf supports -v @@ -309,8 +314,8 @@ __git_ps1_colorize_gitstring () # \001 (SOH) and \002 (STX) are 0-width substring markers # which bash/readline identify while calculating the prompt # on-screen width - to exclude 0-screen-width esc sequences. - local c_pre="${__git_SOH}${__git_ESC}[" - local c_post="m${__git_STX}" + local c_pre="${GIT_PS1_COLOR_PRE-$__git_SOH}${__git_ESC}[" + local c_post="m${GIT_PS1_COLOR_POST-$__git_STX}" local c_red="${c_pre}31${c_post}" local c_green="${c_pre}32${c_post}"