From patchwork Tue Aug 20 01:48:25 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: avih X-Patchwork-Id: 13769253 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 46ED81C6B2 for ; Tue, 20 Aug 2024 01:48:38 +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=1724118520; cv=none; b=WQhS6Ae2jm8i9dT60eVgzvT0NAA+lWtqi1kpanmOebxKVAPb8b/Jt+/hIX8GCgSHRpt0ZNGaxYJe6a9APjO7UYV4thfU8c3xo60f4VNfQFcjw0hYPYcPfaZDykYU/e7nNufIEprM3OIk9Pgd6m7Na1H6vKAas9x6PXfVwTSHGEs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1724118520; c=relaxed/simple; bh=sipFw1dJc1zbv6tyF/MqIbyJnlnjC/BLxSZ5WN2aGTs=; h=Message-Id:In-Reply-To:References:From:Date:Subject:Content-Type: MIME-Version:To:Cc; b=JWrlZ4SOuUWN3qTVPo7wQMFICxhkCQVw1OJdDXGmzvk6OIiOQspTHgAPvbzAotVgk8JZOhCvIJoTxvYgfQ7dzCTGQbLeZ5qE6d1oT6lPrIUHbToqfu4STvpG6oyhYctIv8qIk6mr8lZL5m1Gvy6Lx86Ivq1qhIg5pURvcU2TruA= 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=SHU8+J2+; 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="SHU8+J2+" Received: by mail-wm1-f50.google.com with SMTP id 5b1f17b1804b1-42817bee9e8so38271235e9.3 for ; Mon, 19 Aug 2024 18:48:38 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1724118516; x=1724723316; 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=SHU8+J2+FoGfWvPv71mYfWGPm89QFY1JWnUpkIUOfObEa3Xz++fIhnO+KXTib0EWGL ND7bLXu8cm+EqJLUtOrTVQbySnWNaJrMzZ3vt1HLcRmcVfHJe4el6YfOq7P2fcVryQKD IQmNSJLydxQJGEOg19CVibkI+Kc2coHa5Mn3PR4vmlUyDUD9p4pP0X9lVIZAJfHd0smE bo71ESbOu/fpCz2sycVcn9vGOzpmBQpOHbcl8OcyRj79ILOrXW3CLCUcMCbgnQensVwg nh33iaNmkmL9/aKkF5mHZo/rxw0d+m1oIbdeCDSN+sZCFPJYu3JLnLs5XYIBIAIdt80t BDww== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1724118516; x=1724723316; 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=tZP228Oew6YEU/LPsHp+L5HJGpp+x+ZVknsLknIb7gBX27C1o6+LEd3SLodc4Y7RuW mI8v5diQ3VoQ9mVjl6O28/I9s9opSlYaSIObsvhrNMiP0l4ZsaLC1MPQPMzgMZ1EhyuW Q3s5H4muoPV+twkQ14F91/r5R2dv+UYgX2Ma2U9ahTj8N5yfRTuOKDomZx4z9Cgy1jSp haGf1ayJGPGk2dgM3V1aAPn/dhHTvm5F4w6+wS5fq0reU4mCTWiyJ38v/XsXeI2NP3A1 BHroc/9m9A7rRzLdjpBdTccxjjl91KiYQbcgFUoofcH0MP8TB+tF46JWDSfNXMcPtyc7 V4WA== X-Gm-Message-State: AOJu0Yzt4lg2FPgZ8W/yU2Ast/5jvzkLgN4Y3gkpdxeo9e+/hJK6YYuy B+vocY9DI9QA2Cat9qPov+VMm+yQFp6O7opHQ8fGiO7rUbJnanUCwDJH4g== X-Google-Smtp-Source: AGHT+IEkdF3oMtuC7h/1W7BzNluYUKN1/BQPgcTQ/jrtV5iGKI1DxCGNHNoOkXF8Bw6bJxISvYhLLg== X-Received: by 2002:adf:f6c6:0:b0:371:899b:5c5 with SMTP id ffacd0b85a97d-37194659e95mr7245370f8f.27.1724118515321; Mon, 19 Aug 2024 18:48:35 -0700 (PDT) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id 4fb4d7f45d1cf-5bebbbe26fcsm6197852a12.5.2024.08.19.18.48.34 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 19 Aug 2024 18:48:34 -0700 (PDT) Message-Id: <9ce5ddadf0bb13229461d67451094a373348771e.1724118513.git.gitgitgadget@gmail.com> In-Reply-To: References: Date: Tue, 20 Aug 2024 01:48:25 +0000 Subject: [PATCH v4 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 , Eric Sunshine , 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 Tue Aug 20 01:48:26 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: avih X-Patchwork-Id: 13769254 Received: from mail-wr1-f51.google.com (mail-wr1-f51.google.com [209.85.221.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 F3455168DA for ; Tue, 20 Aug 2024 01:48:38 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.51 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1724118520; cv=none; b=Kya3L75w2SlfusLd6m7KZ+eP0xDadmSxzrxkQfClNKaLMy3U1VNLt7Zt0hGA8SvPS2slwUxNBNyC9dFlTmFgHIhJSLFrNTdrnx9CjXjEmmXkkoBRCwsrfAlHS3wmXScxUEv6xmbrHULg/HrVJE6ZJoUFdV1qTI8NuZMBucpUaB8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1724118520; c=relaxed/simple; bh=PeWD7Xzsyt+Jh9Nqsn4TpYWX2egoJFqBtWAUMS9nZWQ=; h=Message-Id:In-Reply-To:References:From:Date:Subject:Content-Type: MIME-Version:To:Cc; b=ah9wWlh4CHUW32gjTpRi0Rou6+s6qksIs/QTpNlsUIPXRBO8eL09SkbcFnfU0U6zRR7N/zvZaog0sKJoAZqohqFC4UbsORWMb4tD/M1CcZ3UPgzEtuFZWXyAyUKk80Dj/g9f2AT8mwns/XV41WNpyg9l40ccCCgC9bHzqd803KM= 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=GKoAu0kf; arc=none smtp.client-ip=209.85.221.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="GKoAu0kf" Received: by mail-wr1-f51.google.com with SMTP id ffacd0b85a97d-3718b5e9c4fso2476204f8f.0 for ; Mon, 19 Aug 2024 18:48:38 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1724118517; x=1724723317; 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=GKoAu0kfJUjmtaBzmLeGDMq3UxhQHrLcqmB8ZzTu8VXxyV6bFKKQ1N3kTMYlkS24PB kKsDNIModejNXE10PKIIIQe7DdjUsfpvdN87j79WTtAurUJSeDTEHH8gJXLdnDYewRC9 GPb12xaOCCPZ8aDnMXfzAUVTfanwfPG1yZVbTyKqo0jB2SjRol7yqIylRH+GuQzcnMar ePBSkS8U0/CJUK3J5GMOOsLvytQJ1s8TELoTEeEqO8DxQNyp0h4dR1cs2f4hvr2lptuH axkykw5EHdRFXg0JNxT8igw4wfNrD/Vm0hsDmqWf+oKVMpNam1hNmpmsV9jmxthxKDF9 HVzg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1724118517; x=1724723317; 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=pWaxs2Q82A2agQnbutKw3efFWu0Od+BWfZhQt1njngADDfWPXqnrK5xDEbowFCElWO aB1K3f0zElwsn46GVpbubGfVUATmfG7iEOpqJQymkYq38JnE4p9V/2S/YYM/bhNmqeR3 HuI7b5LG7LKk0OE/2Dv9WB8HvlDVJDwuDVCVDpPkbxySrf+Oy6LPe3xAnoxXMu3gIpvD ajpdEmzzyZhltjTnRxYs+sK6ezyGA0H6G56N4hTO1CGYXUl2RvBNJcaujiIGkwwQmpA3 JbY4ejXLHNkZOtzQNYfAuodKbVgLPGYAc9HkOC7yMGU83WT1uyo42zCwie9Oc6wRQLKB HVNw== X-Gm-Message-State: AOJu0Yx8PwnFbfn51xknrCBcL1b6IXiNY9+xtUaH31tXdbTwrT39s/NT fN7XTrPGNZ9fP3sXQ2syKs+4Iwdc6/zKmDQYwvhL7T77JZyp/4WiBEOktA== X-Google-Smtp-Source: AGHT+IGev0l57w4xowoYvJ5EH7Ym6s89T6ObIrt9/ZfbxogCiRZQkMfry0Lf5nL/Nv7UHR4TxKwX4g== X-Received: by 2002:a5d:52cf:0:b0:371:8d47:c17b with SMTP id ffacd0b85a97d-37194653697mr7497150f8f.30.1724118516379; Mon, 19 Aug 2024 18:48:36 -0700 (PDT) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-a83839344fdsm697933466b.100.2024.08.19.18.48.35 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 19 Aug 2024 18:48:35 -0700 (PDT) Message-Id: <680ecb524040c64f886c4e484a64f0d17b512e27.1724118513.git.gitgitgadget@gmail.com> In-Reply-To: References: Date: Tue, 20 Aug 2024 01:48:26 +0000 Subject: [PATCH v4 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 , Eric Sunshine , 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 Tue Aug 20 01:48:27 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: avih X-Patchwork-Id: 13769255 Received: from mail-ej1-f52.google.com (mail-ej1-f52.google.com [209.85.218.52]) (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 0092A1BC4E for ; Tue, 20 Aug 2024 01:48:39 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.218.52 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1724118521; cv=none; b=ewkIXu2VfXApkJhYilBTgIIfDJPi7AZnyzN7FHgFAFTlv9B4/8LAO4FmapSZR32gukjTbq941yp+qeGYO2gg50/6lJSIazmC6YyI0M5yGfE8+XnI9rXpsjZMjGWUXGGy8ar2knW/I39Z3fewl9yUo2L7DkOYict+devJnV5V5S0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1724118521; c=relaxed/simple; bh=p/jqA9gX8l00DDL8hIGrnZJ3zN3+zLxdtSLBkGRh4Gs=; h=Message-Id:In-Reply-To:References:From:Date:Subject:Content-Type: MIME-Version:To:Cc; b=IBZB2/f1/A7XKKPjRl+VLOOOVHRkPLJpAkutReoWM9/yNp/wUwA4GT3x/rpIkb+40qxuWJEETwonbWTbSHyqQ8f1nBVqzsCzD49NVOdexcbmg6xxrc+qmMqXfHwZFWfxVTKR1JHrGH2TsdttFU91PFTVPcsvbaDfc/L/7D0Oh/w= 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=I/OBZvYl; arc=none smtp.client-ip=209.85.218.52 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="I/OBZvYl" Received: by mail-ej1-f52.google.com with SMTP id a640c23a62f3a-a7ab63a388bso211692266b.1 for ; Mon, 19 Aug 2024 18:48:39 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1724118518; x=1724723318; 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=I/OBZvYls8uko8e7aty8nqGnZFFSTP+m5KQmoxA6jzwCJ6vh0s6t1mUxlE5cLEXDRF NjuqMLv7ZVsnSbZYjHEPnHmZJ5pacbeLphpz3IeiEyt8f7FVxmNwOX3neKSwf35pEPCX 3q0Jhej7EkTrRvVF6wFEipIOYJh/3c1Qer9xuuz16ANrGnryxrfqnIB0TH+4/FtDMbVR yh3YDtGDoizoRaAyc70w7ChJUWS4hXHlkFt8MNITgrErkcPT9kz0vY5/HKlueswyadJt kQpbu9ww0JwM+deIc/xKUoRaSNnPX4X0cY1huQavZaG+fSn5v6BsdSJWEL4EueMXE97+ 8wow== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1724118518; x=1724723318; 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=sgICCOnIM0KMhGz61fveAKzOSLkJV0Q3R6GSoT0k82Si3p36LvXvM134Dqbf08argA epwCM1dpjGhLpfsnurTCKdniDdoGcHHXg+CSoIjCg/DmC/J2VscpJM7GRv10ELma9C5O CdxS+JA1TO3SFJKHuYfylr623ueZsXKjyeJ8DxtBbp5nI+Ii7jkPt7DQPYgvHIeKXKfi OwTpGKM6Feb0fuMa7vkrWJVHvBG8ER7QjPcMgiGfihSO9EqY7fCLCa8etecpvAFdHZr8 4QHjjV4OOSXrJ0omGgDaZrPwIxgHxCPbQXgOUN7YkmbOk8xRQxSbDSdCG7fYGQl6ZhV7 Tb1A== X-Gm-Message-State: AOJu0YzObWZyTz24FRYOlFrrV5YrY2itPfLrp3coF+cP4qLRXbnizRxl Uyix4hPLfNHzr2P1kqYb0oJXRZ0GkwTVQ4aPzWHQvlaZUsfpBnRF+VWQUQ== X-Google-Smtp-Source: AGHT+IECgQHJkj7YuNtqxiiADIjLVd1guZ1ib+/QUZZAIdzRp4e2BPtF4VHkSXS9LWp7Avr2V26NqA== X-Received: by 2002:a05:6402:1d4b:b0:5be:dbb6:9cb2 with SMTP id 4fb4d7f45d1cf-5bf087ff722mr1955625a12.20.1724118517244; Mon, 19 Aug 2024 18:48:37 -0700 (PDT) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id 4fb4d7f45d1cf-5bebbe7f191sm6146596a12.61.2024.08.19.18.48.36 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 19 Aug 2024 18:48:36 -0700 (PDT) Message-Id: <7e994eae7bc3dfa021262410c801ddb124ce24f1.1724118513.git.gitgitgadget@gmail.com> In-Reply-To: References: Date: Tue, 20 Aug 2024 01:48:27 +0000 Subject: [PATCH v4 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 , Eric Sunshine , 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 Tue Aug 20 01:48:28 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: avih X-Patchwork-Id: 13769256 Received: from mail-ed1-f46.google.com (mail-ed1-f46.google.com [209.85.208.46]) (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 7E1F3200A3 for ; Tue, 20 Aug 2024 01:48:40 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.208.46 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1724118522; cv=none; b=E5hLa41bmzTOmRRDhAcV4m/stQg9FUZI2nD72VbCaal6neYfQJCDqMsfTjz1VnT5X/rCPM6Gwa1DVvDFAHMn/pm68YsREmcW0I8hpqW34s2OjzgbY+SWGSH6sV03Q30y9aZT2gGDzAauv9qPhcnY5okGmrsTrt+eTI7glswlXI8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1724118522; c=relaxed/simple; bh=Y/eflf72LHbfyadXjodWb8yDEzd6vBwvAvyrlVdBjOc=; h=Message-Id:In-Reply-To:References:From:Date:Subject:Content-Type: MIME-Version:To:Cc; b=Q5RTjR89HCGEqLOir8YW919QOt3UZ/TML2EVJk0firuKO/dSWwBNTGdSGoVIL4DsYVA6NBgo+b+2DWo9aXvN9zPXlA9r6rXGb0MNPNy3az6fJY5TCOfx6NicepLCH3MgNap8WhxVK7ojNFAXr0Dt/NrCjCvo3iFURZpqN1uKPQM= 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=XYI0g08V; arc=none smtp.client-ip=209.85.208.46 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="XYI0g08V" Received: by mail-ed1-f46.google.com with SMTP id 4fb4d7f45d1cf-5bebd3b7c22so6775721a12.0 for ; Mon, 19 Aug 2024 18:48:40 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1724118518; x=1724723318; 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=XYI0g08VCMaVQQ0zEyzaudL63s47yGw830tdICWb0mDzzOLN6F2UQsBvi4dO9a6jNS IdxWzY0BbU9Ph0gMQj9DQ+K2dcbsDwPs0xTMLIt7Shs1E0vmvnYpVHQ2DzHsehT8vGcZ UCYQs+z5G1AacEWY8+/S8SHpSGi1wC424wd2LS3i78RTRkFiwiW/mkgLBH2isWmBPF5W jL7Qelgun4I6QhG41tuLV9KRMCv5TGyaB4XVmTxRoMWV13jvc6dd3guudAjyCEOlMKU3 RLCRSghZgM8iHM3qK1Wmnu18v38BJTwa4BI03w0Nx3OERaxHqTJa2P/Vt0n/R8Rz/S53 MgEw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1724118518; x=1724723318; 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=S84fh3JsQH+jVxYrbwrHLAuJCZ6rBUMo32cDM7lS12bEdp9cMduAJsHQnlzeAz7t9P N7RInQFhVCigbLkIGy3a9DlnyzVElS/nTObS2D6sHynYpEXwdbbNSfXK5LuL83e+45wc sBLbZUP7UO0Gt9qtxMSNlovbT8g8IbsFJ8skJ8WGQTG733sICf8IOb/w9VjW/iWVKL0I Gmdw5brb1JtUrVVQSWDQ+f/Wd0Rhw9wSIunKUgKPSI4eKZC7t0Cz+Z3Zq+pqFnz1rPpx qi0PmNfcanFabahDXKppHDHpR/bNQROdB03fPZFRZn/h7hK/c7Gg0x1yEB0rS4CX3Yix 3L+A== X-Gm-Message-State: AOJu0YwZ9O20wAz8eyzMkM6FFBH1i7xpkdOh1bVrozB+nhk1p3y+qWA+ CaxsjMkMIAlaYxjGnNfotZtJfoSpgQ84GnKd8Unyazgz3Jk58C0LLhvfVw== X-Google-Smtp-Source: AGHT+IFkPLEtgf0B/3DwpiGJicD7Qe4Ff3oTn2Z5YMM0jPamkF2zlG90JVR8f0FqbMD5Ldxh+esH3A== X-Received: by 2002:a05:6402:2087:b0:5be:ddbf:c81e with SMTP id 4fb4d7f45d1cf-5bf0ac39256mr1210828a12.12.1724118518026; Mon, 19 Aug 2024 18:48:38 -0700 (PDT) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id 4fb4d7f45d1cf-5bebbde48e7sm6341294a12.26.2024.08.19.18.48.37 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 19 Aug 2024 18:48:37 -0700 (PDT) Message-Id: <232340902a1feeafe526528eb88b8d0814d11545.1724118513.git.gitgitgadget@gmail.com> In-Reply-To: References: Date: Tue, 20 Aug 2024 01:48:28 +0000 Subject: [PATCH v4 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 , Eric Sunshine , 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 Tue Aug 20 01:48:29 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: avih X-Patchwork-Id: 13769257 Received: from mail-wm1-f47.google.com (mail-wm1-f47.google.com [209.85.128.47]) (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 CED542B9CD for ; Tue, 20 Aug 2024 01:48:41 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.47 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1724118523; cv=none; b=PXoih6Hyuk95xoIMg+yjHwO/E1qE40lV8ICx9ks3l4YLJ/9NQrB8xqu9bzedruabQJOl1uveDOaRLXxJPkO27kF95ZogGzk8KC7BP52ENc+IjfpXEnY/IV6rkNsb5aZ2A5OIKAt5+ZZRPCvlhv4oXfGRcg7gPnNMjghHagR7dpk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1724118523; c=relaxed/simple; bh=M/Fo7zXTNw9Y/Hs97vlrJ4YjHA1DEGeiTDJiw/MrEJg=; h=Message-Id:In-Reply-To:References:From:Date:Subject:Content-Type: MIME-Version:To:Cc; b=JK6twMIZ8AhA3M2dryAYhtDC/GT5RYIFHdHTSwrpUwnB+vaOJjDzJqfWBYNi3ljgTSakR35f0ae8ZTGzKzTnf310pGIFkLcAf5px74W4mv75i6ayuH0qPxLaJlAt8G46qcHS6NAYXd1Zpl3WXAsUVyTTRsAWqlbFnzb+zOdyjNU= 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=iTLWBVXg; arc=none smtp.client-ip=209.85.128.47 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="iTLWBVXg" Received: by mail-wm1-f47.google.com with SMTP id 5b1f17b1804b1-428ec6c190eso41422635e9.1 for ; Mon, 19 Aug 2024 18:48:41 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1724118520; x=1724723320; 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=vs3xzSHBsIumh6tvWhdotqxT8hZDQyuHe3M7Qqg3wy4=; b=iTLWBVXg9Yr6ssa5j0sNX9vkxvvvOgTu8pREXwhXxyadljJci+KsQNR2Bcxgu4gqJD sdudt1qsy/Y2vCHF3a70n0PxQoWp2rncK1fd9TXsvTbeH3G6n6QnRiSZ6KJ8SR7NHJ2V +rRzXK0rCz4XmWf+HuKbdud73ozQ7UUxoeRTes9ujDyIlN4SIGzpKx2CZHoabraOHc2g iNJFE/cTUU6grEqnNF6aEnpyRdcPA4P/lH8ZU7SacKDsx2AMPHYh/ddkbuw/eE9IhrAN lD2k0AD6TXmxVH3o3Tj0n1khtg+6ay5u3fOOT8/VlrRMGXA8Uju9fuRlxR5P9zMHvmol AsyA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1724118520; x=1724723320; 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=vs3xzSHBsIumh6tvWhdotqxT8hZDQyuHe3M7Qqg3wy4=; b=LczEGmQh5WgCGDcF/Gnf5dpp5Qw8bG88td2WVAFLHGDwe4lRzkuyxlrQliwZw1MXtF RXZ8pnnBvTvqym2l3B0KIG5NREntCLScPC0+RO99YO07rynXO6RDf1U9w0NllzidliV1 xBORvsuzBKoQ2593FOogd5PgLHNp+01TFeX5uAN3mJJZwRVgBwPgz3vkIyTaLWnqeqBT 35sVTs3Qth9ORDpjEhbW+DEdgVZQEtCJLnP0A6XXc5Q+ZiTnjs8plq0J9gUFhZO8JJOX a/Y8xczhMdu6mE03biI+aHwSzQ7p6asJmm0GDxhXc9BgdcJP/QMDEs5gWYEO5x7ugcvf rzww== X-Gm-Message-State: AOJu0Yw76Tfd8jb7qRfd5SPTMPZmhd2dvl8g5fDsWH+ANSoynmUFpDa5 4xXl1lDCgyoYvfG4pKnhPmAF1ya3ELvDZBLJUrK+inVJFAvynWxshTc0ZQ== X-Google-Smtp-Source: AGHT+IH1p4eKBqtr9ZNAB/0Sk9/tpmMyV8zrTUWj/SobZofuFf2I5aJHscmQm+ocgu4JQHruAp/hfg== X-Received: by 2002:adf:ed83:0:b0:36b:a3f1:6333 with SMTP id ffacd0b85a97d-371c5fcb478mr276324f8f.24.1724118519168; Mon, 19 Aug 2024 18:48:39 -0700 (PDT) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-a86475b0f69sm34665966b.198.2024.08.19.18.48.38 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 19 Aug 2024 18:48:38 -0700 (PDT) Message-Id: <18ff70db6b3616a9b933b44bf4d44c4405038728.1724118513.git.gitgitgadget@gmail.com> In-Reply-To: References: Date: Tue, 20 Aug 2024 01:48:29 +0000 Subject: [PATCH v4 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 , Eric Sunshine , 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 guidelines here for future reference. I'm leaving it to someone else to decide whether to include it in the file itself, place it 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 Tue Aug 20 01:48:30 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: avih X-Patchwork-Id: 13769258 Received: from mail-ed1-f48.google.com (mail-ed1-f48.google.com [209.85.208.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 8BEEC36B17 for ; Tue, 20 Aug 2024 01:48:42 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.208.48 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1724118524; cv=none; b=fZGTKfZ8KvnD1ce9hTEondjCIdrk7HX0DphpyvuAeSLPnjO0DbkCmthcUeiQi2Jl4hqBYLahjdYHNzwkrW7ZTNjekTy0OoQrzcuJZoAsHsrglsW2TnZEfc/bcEJxzLAnmW38BR+qXDPFua8bAgriebxWVPgv9VpOF6fE9QjhxOU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1724118524; c=relaxed/simple; bh=+OzamXJet4poQcDjfbocCqRQTImWRURbURYBdomHj0o=; h=Message-Id:In-Reply-To:References:From:Date:Subject:Content-Type: MIME-Version:To:Cc; b=Th7UmImWR3sA5zciUARf4x67zHjsyRLZcdFvdtbgVaCB67Tf1MH0B/Nn/hrl0+9m9rvV1v1vVrpKKNcFjbXIGGO31NoybxaRVYwfXquU00KE1JPgI0OdNZXdfDZdKrA9GNtMzsAQSk4n/Ai351ZrXH/LbWdqdDYdGeP0kxHWBKw= 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=S6vlAY7F; arc=none smtp.client-ip=209.85.208.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="S6vlAY7F" Received: by mail-ed1-f48.google.com with SMTP id 4fb4d7f45d1cf-5becdf7d36aso3816677a12.1 for ; Mon, 19 Aug 2024 18:48:42 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1724118520; x=1724723320; 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=S6vlAY7FqFIT0wbXG/D/919H5FCQPX0bGvjk3/ylILOqr4a3oWCD5HRWf+nQdN/k/M QoM0R5BZTU3GvTuIzW00TIkaLo19VxdUztVc/tXGyxKHWxVrYMeKa5B3EB+/cL1iWMIX /J4aHc/CSdoavDvDx1XoA5QdXPtCb0zIYP3CzDjwDcd7jCwg2Gpgh0QWX+gCHegoBkcZ RGxErltUrIX8YcIP6sjp/qbWBnafFNI4tAzPA9fAlmOhGx2q8m7bvPlsWvrfWVPe78S5 oq0qitbR6C3LyqbuUghYEZwUTxEmdOzk7rZXE6zoqdX2BWlcrQwWuDuzMe3nnuoCruQm 6J0A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1724118520; x=1724723320; 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=nAnQcNB57T6/ZBuUVJomv99A5LaKCGus8J8l/xve/vQtsHiFRHNFY1rwJ4u/rGugoP WeJKw09hywaUiFIOI9rbncn0+qZT3iX0s6aKsxayXFNVLqDGK1H6cCAnzk35hLtqckRD voctzSQs6F2f3HHIaG89q0pYx+J10LRWJ9lbsGP8fiRkGS1Ni/wyPOSCf384/H8QPc8A BZPowgpaiZf+vNbeVXV29o7Z+dTz178s1xhBAl7RCcHSre3zOIr71KRY/+qr7Fd1ij/q hDdsq+t93KskeMyFQIOkkoEK33cKxGNqD/S0tbpMHibQfBnM4EJr1f0VwsGpPwCGsiK9 pQOg== X-Gm-Message-State: AOJu0YzzH17xTqH/XcX0qdHzGc2Etrpy+LVX7wIRkV1X3JJT84DsJQly xF5NTYf1aaXMCYsoDA1nEiyze/BrqR9TfGQ+FVrUzbvrq9z/SYaVKXuNIg== X-Google-Smtp-Source: AGHT+IEwA/iBGUtMTS0hIHvTPuexo2Pjnkq9jLooQJDT2NCXjYq06384Vytz8+XWuHxIJbgAMso06A== X-Received: by 2002:a05:6402:4020:b0:5be:d7d8:49ac with SMTP id 4fb4d7f45d1cf-5bed7d84b61mr8064337a12.11.1724118520056; Mon, 19 Aug 2024 18:48:40 -0700 (PDT) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id 4fb4d7f45d1cf-5bebbe7f92dsm6147730a12.60.2024.08.19.18.48.39 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 19 Aug 2024 18:48:39 -0700 (PDT) Message-Id: <48aa31feedb117a687484651378fe682fe7c39c8.1724118513.git.gitgitgadget@gmail.com> In-Reply-To: References: Date: Tue, 20 Aug 2024 01:48:30 +0000 Subject: [PATCH v4 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 , Eric Sunshine , 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 Tue Aug 20 01:48:31 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: avih X-Patchwork-Id: 13769259 Received: from mail-ej1-f49.google.com (mail-ej1-f49.google.com [209.85.218.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 51DD31BC4E for ; Tue, 20 Aug 2024 01:48:43 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.218.49 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1724118525; cv=none; b=ZlME14us3VaqJDzFeZSn4fwhrx4gdZvfYNrQwkeEB3mEHzP2TA9WSF1pBdhjdmYjjnL6xJLCUWdc25hxAHYHq6+B5jQBDBp+gKqwov1JSHVrhfQQZ2XDkUBh3XwjXwy2kJWTBG2tVGcJnlP52xEA0MCLZJF6RLXdd8i51kxkBy0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1724118525; c=relaxed/simple; bh=Y2btUPlnWF9x450ZcUCJVsOoWZUW+2KGM+sT5G0fyQ4=; h=Message-Id:In-Reply-To:References:From:Date:Subject:Content-Type: MIME-Version:To:Cc; b=PPeJ994HZRYtXwtPlcpCEeXWXgYM7a0Dsu9C/xFBWKUUyieV87Iy5AqRoEezKTWlUB40sw3ZuJgSoIjfkrz/Fi7dBNMHK+4UiaQSbB8OPAadOxB5sP6IAt4gJD/FJxABBPTMPv46pQnB+4v5AjPsmcowXPzg+8CGdvJGobJEpaw= 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=ABI9Zr1t; arc=none smtp.client-ip=209.85.218.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="ABI9Zr1t" Received: by mail-ej1-f49.google.com with SMTP id a640c23a62f3a-a7a8a4f21aeso604946266b.2 for ; Mon, 19 Aug 2024 18:48:43 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1724118521; x=1724723321; 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=ABI9Zr1tiCiNnllWRLcdPmHpQWdjb60K8og0sxG5mcbyFBgP1vVwz7+pScvirRCumu iAEQaYtEcB/2MqjlDSq/C61u9vFE2WITMfAHOpMxaos8cwDO9YC3ZHgPX1a3Yf90WWT8 G2ZCLALX+TGyUl1SWzcofj/KqgTi9BJAdeuyyBXiADiWeLLlt/KORd9YA2qQwD0yI2sn tVpiPE2hdTA3oZGJGg7f/P4xdD8oVFfJa/28L2Zokf4TFW07ruM2W+l5/XpbOlWlcN00 VuaiLjBYVtCi0Xw5NhIRTPJiWA4vHg5FeTEDItp881dL6jI5MQ8hHKXYjZrEfyen2LWl ayiQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1724118521; x=1724723321; 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=rWF/kiupQINHbJSiPv9so/E7cPtlyUcl/GmP7R6at+TS93yyfdVtTC/b5jQ5+mgrno 9j2UAF6XmOo9EGI1Z/22snwjXm2Iu9gf8SexToH4LmgRCLIczTm/MuqwJz/7MSESuXW7 1xf/BQfWSk6F0Sbfu5hKOIojGRcpDCDNjbXfHmFNl1I9WCNlLSLqrkfNKGBJqnZlUWWD ov9r4IwRGa4SUe45wXlmaF7wd+7QeNUC+gfGtPnuwuqDicBgP75Q/0WxO+G6epp8BBpJ TjrocOlvs/StB5wDMMchDxyzRpPIB94GcQFnpVGwlMkBG0x41W477POSC1jND3QigGjM pp+w== X-Gm-Message-State: AOJu0YwmE0cTwY/tNN0bST1++6rjd8hzv7a6gGFwGuZqkkNXNajVPIpx nfha9mUIRv/xEeepjW5cy3lo4Zct5kEPSlYj7hWJglgNiWsaZnac2nRJDg== X-Google-Smtp-Source: AGHT+IEX63Pw85oiYdL7v4xsaIdYvXZiREGy/ul9NAnFWiDVMxT1RByN1+OPLVLXeeITikckKgTl5g== X-Received: by 2002:a17:906:f5a7:b0:a7d:a00a:aa02 with SMTP id a640c23a62f3a-a83928a64fdmr858868466b.1.1724118520788; Mon, 19 Aug 2024 18:48:40 -0700 (PDT) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-a838396cfa5sm694192566b.207.2024.08.19.18.48.40 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 19 Aug 2024 18:48:40 -0700 (PDT) Message-Id: In-Reply-To: References: Date: Tue, 20 Aug 2024 01:48:31 +0000 Subject: [PATCH v4 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 , Eric Sunshine , 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 Tue Aug 20 01:48:32 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: avih X-Patchwork-Id: 13769260 Received: from mail-ej1-f51.google.com (mail-ej1-f51.google.com [209.85.218.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 280203B796 for ; Tue, 20 Aug 2024 01:48:43 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.218.51 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1724118525; cv=none; b=BgTPim8FnG/07XTBWbk/zeCirQBU8T2DZakT4yvydvYj79c2wd0zswQNCDvaoFwXSBJa5cB3D+YaQAkgSjWyi+arcuUsryKoyl+0WM29+XdC3V5JSiq3buPXHILOlpceJFZzFX8hT3p2O8pzJqS3UtkzTEm7nRyqkAlnrem5a/M= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1724118525; c=relaxed/simple; bh=04M2SA6KLr1ytY4c4zDyaG6UDDk0NJk+zVZ7zJ5EVPg=; h=Message-Id:In-Reply-To:References:From:Date:Subject:Content-Type: MIME-Version:To:Cc; b=gKgtPB57BAyKTY9cOZbgQkQdkxplmYqLSRuzq92KqoaHKUZ9R76MNpaxzPnYMKSlWU+k1nyA++RsPkXtJo0Z+pacn3L7So1MLVziZmAEtT2FP2QZeJBriU5G0XLczvtjp/mMVGkF/j/82nzqAbfjKf7LxZGgny5au9yPeRisDcU= 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=HlyibtG3; arc=none smtp.client-ip=209.85.218.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="HlyibtG3" Received: by mail-ej1-f51.google.com with SMTP id a640c23a62f3a-a8657900fc1so127866b.1 for ; Mon, 19 Aug 2024 18:48:43 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1724118522; x=1724723322; 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=HlyibtG34BWAi0IKjmcWrLE+Uf26iINdagPCCqJui3YkhRyQzBPuOaYbc4+G4MzDAU jOceT6W47kzOKfF6ZPGRwerlYp3ISFKR2TrB7YoEpnFOx44ee58A8N4mRd8CzaxEbbZA qIjqySA73ckIiifo2xFZov8TujuffKIm17jHxgKHz8nz6xK+kf+IHtI4pGnKd3Fmndek oXVGmyQxGKbJms+rW2e19qY+l34zKEHDHKxWXa79p0uRUEE1/Lc0hQytzrZYBmpPDVka U5m1d+/X1Ys+XzC6iLUjNlKR29SbDrHIvWJFb5HAaUVGkkXjHEK8NgzrIUXy4xhnlEhY n1Lw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1724118522; x=1724723322; 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=I0QgnEQoZbt6t9H60fqLsBo68iXHZSYXz5vzIe7w/WNWCmeYkyXW16iA18oXo8dOuG qGEhz0iYP5lCrIHjsNjuENivet4wl+OpC17p0yz+amCpPf6zk1IWBoM/nXhLIRYcy8J1 LzidoVtYY8ophNoORohGGF6d5pZmMVZQ56KGqNuEqepomq3wV5VQvJIVDgAsUQQrSbAk YzFK8TDodkO9ntQFy7gqhyrEKQA52U1m1Uu0Y35rS2V+t/iPOrCiCbicAsaGjQYwMgWM ogsx2K6LoJHK2JpWNJpkCpQdK5xIk6wc1w24131mMY4val26AQAjS+NI8KW8coGViAfs 85pQ== X-Gm-Message-State: AOJu0YwZcnnHJYsY3MKyef/dM7i91+U7ePsjrP2JDnWMPp6PspCHn04k pc/wBCIJEFObRRBxPOdd/iSREXECHpKF0gWCJP0kEDKsK+xqZtmTFE1dTA== X-Google-Smtp-Source: AGHT+IHuViXBbSBFR5TP+5qU9EwUzb3raZM/wRQKxqATDShxTy64oMU+bcxGM4rOXPc1Yba4hvuf4A== X-Received: by 2002:a17:907:2d88:b0:a7a:c083:8579 with SMTP id a640c23a62f3a-a8392a4b2e0mr918099966b.62.1724118521586; Mon, 19 Aug 2024 18:48:41 -0700 (PDT) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-a83838c652asm707980266b.12.2024.08.19.18.48.41 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 19 Aug 2024 18:48:41 -0700 (PDT) Message-Id: In-Reply-To: References: Date: Tue, 20 Aug 2024 01:48:32 +0000 Subject: [PATCH v4 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 , Eric Sunshine , 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}"