[PATCH] fast-import: do not truncate exported marks file

2016-05-17 Thread Felipe Contreras
Certain lines of the marks file might be corrupted (or the objects
missing due to a garbage collection), but that's no reason to truncate
the file and essentially destroy the rest of it.

Ideally missing objects should not cause a crash, we could just skip
them, but that's another patch.

Signed-off-by: Felipe Contreras 
---
 fast-import.c  |  7 +--
 t/t9300-fast-import.sh | 15 +++
 2 files changed, 20 insertions(+), 2 deletions(-)

diff --git a/fast-import.c b/fast-import.c
index 9fc7093..a975c34 100644
--- a/fast-import.c
+++ b/fast-import.c
@@ -329,6 +329,7 @@ static const char *export_marks_file;
 static const char *import_marks_file;
 static int import_marks_file_from_stream;
 static int import_marks_file_ignore_missing;
+static int import_marks_file_done;
 static int relative_marks_paths;
 
 /* Our last blob */
@@ -1802,7 +1803,7 @@ static void dump_marks(void)
static struct lock_file mark_lock;
FILE *f;
 
-   if (!export_marks_file)
+   if (!export_marks_file || (import_marks_file && 
!import_marks_file_done))
return;
 
if (hold_lock_file_for_update(&mark_lock, export_marks_file, 0) < 0) {
@@ -1835,7 +1836,7 @@ static void read_marks(void)
if (f)
;
else if (import_marks_file_ignore_missing && errno == ENOENT)
-   return; /* Marks file does not exist */
+   goto done; /* Marks file does not exist */
else
die_errno("cannot read '%s'", import_marks_file);
while (fgets(line, sizeof(line), f)) {
@@ -1865,6 +1866,8 @@ static void read_marks(void)
insert_mark(mark, e);
}
fclose(f);
+done:
+   import_marks_file_done = 1;
 }
 
 
diff --git a/t/t9300-fast-import.sh b/t/t9300-fast-import.sh
index 25bb60b..4bca35c 100755
--- a/t/t9300-fast-import.sh
+++ b/t/t9300-fast-import.sh
@@ -2650,6 +2650,21 @@ test_expect_success 'R: ignore non-git options' '
git fast-import expect <<-EOF &&
+   :3 
+   :1 $blob
+   :2 $blob
+   EOF
+   cp expect io.marks &&
+   test_must_fail git fast-import --import-marks=io.marks 
--export-marks=io.marks <<-\EOF &&
+
+   EOF
+   test_cmp expect io.marks
+'
+
 ##
 ## R: very large blobs
 ##
-- 
2.8.2.dirty

--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] fast-import: do not truncate exported marks file

2016-05-17 Thread Felipe Contreras
On Tue, May 17, 2016 at 5:22 PM, Junio C Hamano  wrote:
> Felipe Contreras  writes:
>
>> Certain lines of the marks file might be corrupted (or the objects
>> missing due to a garbage collection), but that's no reason to truncate
>> the file and essentially destroy the rest of it.
>
> Hmm, so the issue is:
>
>  - we use die_nicely() that calls dump_marks() after writing a crash
>report as our die_routine().
>
>  - when dump_marks() is called, and export_marks_file names an
>existing file, it tries to write marks in it.  If we let it go
>through, we would end up writing a new marks file based on an
>incomplete set of marks we have only half-read in the earlier
>step, which is bad, as the resulting one is incomplete, and the
>original one that this replaced may have been a good one.
>
> Is that what this change addresses?

Yes. As I said; the marks file gets truncated.

> I am just wondering if a solution to preserve both files is more
> desirable.
>
> This change looks a bit over-eager to discard the dump die_nicely()
> is trying to create in one scenario, and a bit less careful at the
> same time in another scenario.
>
>  - Even if we are reading from somewhere, export_marks_file can
>point at a completely new file that is different from
>import_marks file, in which case, we are not really losing any
>information by freshly creating a new marks file, no?

Right, we are not losing any information, but we are not gaining much
either: it's a truncated version of the import marks.

>  - Even if we did not read from any existing marks file, if we are
>given export_marks_file that names an existing file, wouldn't we
>want to avoid corrupting it with a dump from this aborted run?

If we don't run from an existing marks file, this patch has no effect.

-- 
Felipe Contreras
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] fast-import: do not truncate exported marks file

2016-05-17 Thread Felipe Contreras
On Tue, May 17, 2016 at 10:59 PM, Junio C Hamano  wrote:
> On Tue, May 17, 2016 at 8:31 PM, Felipe Contreras
>  wrote:
>> On Tue, May 17, 2016 at 5:22 PM, Junio C Hamano  wrote:

>>>  - Even if we did not read from any existing marks file, if we are
>>>given export_marks_file that names an existing file, wouldn't we
>>>want to avoid corrupting it with a dump from this aborted run?
>>
>> If we don't run from an existing marks file, this patch has no effect.
>
> Yes, that is exactly what I was wondering if we may want to improve
> while at it.

This doesn't make much sense. Corrupted from where? This patch is
tackling the issue where the imported marks file is "corrupted".

-- 
Felipe Contreras
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 01/11] completion: add missing fetch options

2016-05-19 Thread Felipe Contreras
Signed-off-by: Felipe Contreras 
---
 contrib/completion/git-completion.bash | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/contrib/completion/git-completion.bash 
b/contrib/completion/git-completion.bash
index e3918c8..ecdf742 100644
--- a/contrib/completion/git-completion.bash
+++ b/contrib/completion/git-completion.bash
@@ -1225,6 +1225,8 @@ __git_fetch_recurse_submodules="yes on-demand no"
 __git_fetch_options="
--quiet --verbose --append --upload-pack --force --keep --depth=
--tags --no-tags --all --prune --dry-run --recurse-submodules=
+   --no-recurse-submodules --unshallow --update-shallow --multiple
+   --submodule-prefix= --update-head-ok --progress
 "
 
 _git_fetch ()
-- 
2.8.0+fc1

--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 00/11] Completion fixes and improvements

2016-05-19 Thread Felipe Contreras
Hi,

Here's a bunch of patches I've been using for a long time. I don't recall if
I've sent some of these before.

Here they are in case anybody is interested.

Cheers.


Felipe Contreras (11):
  completion: add missing fetch options
  completion: bash: remove old wrappers
  completion: bash: remove zsh wrapper
  completion: zsh: don't hide ourselves
  completion: remove zsh hack
  completion: zsh: trivial cleanups
  completion: bash: cleanup cygwin check
  completion: zsh: improve main function selection
  completion: zsh: fix for directories with spaces
  completion: prompt: fix for Zsh
  Revert "Update documentation occurrences of filename .sh"

 contrib/completion/git-completion.bash | 86 +++---
 contrib/completion/git-completion.zsh  | 26 --
 contrib/completion/git-prompt.sh   |  8 ++--
 3 files changed, 20 insertions(+), 100 deletions(-)

-- 
2.8.0+fc1

--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 02/11] completion: bash: remove old wrappers

2016-05-19 Thread Felipe Contreras
Signed-off-by: Felipe Contreras 
---
 contrib/completion/git-completion.bash | 12 
 1 file changed, 12 deletions(-)

diff --git a/contrib/completion/git-completion.bash 
b/contrib/completion/git-completion.bash
index ecdf742..5e2e590 100644
--- a/contrib/completion/git-completion.bash
+++ b/contrib/completion/git-completion.bash
@@ -2754,18 +2754,6 @@ __git_complete ()
|| complete -o default -o nospace -F $wrapper $1
 }
 
-# wrapper for backwards compatibility
-_git ()
-{
-   __git_wrap__git_main
-}
-
-# wrapper for backwards compatibility
-_gitk ()
-{
-   __git_wrap__gitk_main
-}
-
 __git_complete git __git_main
 __git_complete gitk __gitk_main
 
-- 
2.8.0+fc1

--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 03/11] completion: bash: remove zsh wrapper

2016-05-19 Thread Felipe Contreras
It has been deprecated for more than three years. It's time to move on.

Signed-off-by: Felipe Contreras 
---
 contrib/completion/git-completion.bash | 64 --
 1 file changed, 64 deletions(-)

diff --git a/contrib/completion/git-completion.bash 
b/contrib/completion/git-completion.bash
index 5e2e590..9cbae6f 100644
--- a/contrib/completion/git-completion.bash
+++ b/contrib/completion/git-completion.bash
@@ -2672,70 +2672,6 @@ __gitk_main ()
__git_complete_revlist
 }
 
-if [[ -n ${ZSH_VERSION-} ]]; then
-   echo "WARNING: this script is deprecated, please see 
git-completion.zsh" 1>&2
-
-   autoload -U +X compinit && compinit
-
-   __gitcomp ()
-   {
-   emulate -L zsh
-
-   local cur_="${3-$cur}"
-
-   case "$cur_" in
-   --*=)
-   ;;
-   *)
-   local c IFS=$' \t\n'
-   local -a array
-   for c in ${=1}; do
-   c="$c${4-}"
-   case $c in
-   --*=*|*.) ;;
-   *) c="$c " ;;
-   esac
-   array[${#array[@]}+1]="$c"
-   done
-   compset -P '*[=:]'
-   compadd -Q -S '' -p "${2-}" -a -- array && _ret=0
-   ;;
-   esac
-   }
-
-   __gitcomp_nl ()
-   {
-   emulate -L zsh
-
-   local IFS=$'\n'
-   compset -P '*[=:]'
-   compadd -Q -S "${4- }" -p "${2-}" -- ${=1} && _ret=0
-   }
-
-   __gitcomp_file ()
-   {
-   emulate -L zsh
-
-   local IFS=$'\n'
-   compset -P '*[=:]'
-   compadd -Q -p "${2-}" -f -- ${=1} && _ret=0
-   }
-
-   _git ()
-   {
-   local _ret=1 cur cword prev
-   cur=${words[CURRENT]}
-   prev=${words[CURRENT-1]}
-   let cword=CURRENT-1
-   emulate ksh -c __${service}_main
-   let _ret && _default && _ret=0
-   return _ret
-   }
-
-   compdef _git git gitk
-   return
-fi
-
 __git_func_wrap ()
 {
local cur words cword prev
-- 
2.8.0+fc1

--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 11/11] Revert "Update documentation occurrences of filename .sh"

2016-05-19 Thread Felipe Contreras
The original code was correct: the example location ~/.git-completion.sh
is correct, because it's not only used by Bash. And zstyle command in
Zsh should use that same location; the Bash script.

This reverts commit 0e5ed7cca3c51c821c2bb0465617e75d994f432f.

Signed-off-by: Felipe Contreras 
---
 contrib/completion/git-completion.bash | 4 ++--
 contrib/completion/git-completion.zsh  | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/contrib/completion/git-completion.bash 
b/contrib/completion/git-completion.bash
index 398f3a7..3224ae1 100644
--- a/contrib/completion/git-completion.bash
+++ b/contrib/completion/git-completion.bash
@@ -17,9 +17,9 @@
 #
 # To use these routines:
 #
-#1) Copy this file to somewhere (e.g. ~/.git-completion.bash).
+#1) Copy this file to somewhere (e.g. ~/.git-completion.sh).
 #2) Add the following line to your .bashrc/.zshrc:
-#source ~/.git-completion.bash
+#source ~/.git-completion.sh
 #3) Consider changing your PS1 to also show the current branch,
 #   see git-prompt.sh for details.
 #
diff --git a/contrib/completion/git-completion.zsh 
b/contrib/completion/git-completion.zsh
index 28eaaed..6075111 100644
--- a/contrib/completion/git-completion.zsh
+++ b/contrib/completion/git-completion.zsh
@@ -9,7 +9,7 @@
 #
 # If your script is somewhere else, you can configure it on your ~/.zshrc:
 #
-#  zstyle ':completion:*:*:git:*' script ~/.git-completion.zsh
+#  zstyle ':completion:*:*:git:*' script ~/.git-completion.sh
 #
 # The recommended way to install this script is to copy to '~/.zsh/_git', and
 # then add the following to your ~/.zshrc file:
-- 
2.8.0+fc1

--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 10/11] completion: prompt: fix for Zsh

2016-05-19 Thread Felipe Contreras
We can add colour in Zsh without the need of pcmode.

Signed-off-by: Felipe Contreras 
---
 contrib/completion/git-prompt.sh | 8 +---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/contrib/completion/git-prompt.sh b/contrib/completion/git-prompt.sh
index 64219e6..0da14ee 100644
--- a/contrib/completion/git-prompt.sh
+++ b/contrib/completion/git-prompt.sh
@@ -502,9 +502,11 @@ __git_ps1 ()
 
local z="${GIT_PS1_STATESEPARATOR-" "}"
 
-   # NO color option unless in PROMPT_COMMAND mode
-   if [ $pcmode = yes ] && [ -n "${GIT_PS1_SHOWCOLORHINTS-}" ]; then
-   __git_ps1_colorize_gitstring
+   # NO color option unless in PROMPT_COMMAND mode or it's Zsh
+   if [ -n "${GIT_PS1_SHOWCOLORHINTS-}" ]; then
+   if [ $pcmode = yes ] || [ -n "${ZSH_VERSION-}" ]; then
+   __git_ps1_colorize_gitstring
+   fi
fi
 
b=${b##refs/heads/}
-- 
2.8.0+fc1

--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 07/11] completion: bash: cleanup cygwin check

2016-05-19 Thread Felipe Contreras
Avoid Yoda conditions, use test, and cleaner statement.

Signed-off-by: Felipe Contreras 
---
 contrib/completion/git-completion.bash | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/contrib/completion/git-completion.bash 
b/contrib/completion/git-completion.bash
index 6c338ae..398f3a7 100644
--- a/contrib/completion/git-completion.bash
+++ b/contrib/completion/git-completion.bash
@@ -2698,6 +2698,5 @@ __git_complete gitk __gitk_main
 # when the user has tab-completed the executable name and consequently
 # included the '.exe' suffix.
 #
-if [ Cygwin = "$(uname -o 2>/dev/null)" ]; then
+test "$(uname -o 2>/dev/null)" = "Cygwin" &&
 __git_complete git.exe __git_main
-fi
-- 
2.8.0+fc1

--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 06/11] completion: zsh: trivial cleanups

2016-05-19 Thread Felipe Contreras
We don't need to override IFS, zsh has a native way of splitting by new
lines: the expansion flag (f).

Also, we don't need to split files by ':' or '='; that's only for words.

Signed-off-by: Felipe Contreras 
---
 contrib/completion/git-completion.zsh | 10 +++---
 1 file changed, 3 insertions(+), 7 deletions(-)

diff --git a/contrib/completion/git-completion.zsh 
b/contrib/completion/git-completion.zsh
index e10df7d..317b8eb 100644
--- a/contrib/completion/git-completion.zsh
+++ b/contrib/completion/git-completion.zsh
@@ -65,26 +65,22 @@ __gitcomp_nl ()
 {
emulate -L zsh
 
-   local IFS=$'\n'
compset -P '*[=:]'
-   compadd -Q -S "${4- }" -p "${2-}" -- ${=1} && _ret=0
+   compadd -Q -S "${4- }" -p "${2-}" -- ${(f)1} && _ret=0
 }
 
 __gitcomp_nl_append ()
 {
emulate -L zsh
 
-   local IFS=$'\n'
-   compadd -Q -S "${4- }" -p "${2-}" -- ${=1} && _ret=0
+   compadd -Q -S "${4- }" -p "${2-}" -- ${(f)1} && _ret=0
 }
 
 __gitcomp_file ()
 {
emulate -L zsh
 
-   local IFS=$'\n'
-   compset -P '*[=:]'
-   compadd -Q -p "${2-}" -f -- ${=1} && _ret=0
+   compadd -Q -p "${2-}" -f -- ${(f)1} && _ret=0
 }
 
 __git_zsh_bash_func ()
-- 
2.8.0+fc1

--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 04/11] completion: zsh: don't hide ourselves

2016-05-19 Thread Felipe Contreras
There's no need to hide the fact that we are on zsh any more.

Signed-off-by: Felipe Contreras 
---
 contrib/completion/git-completion.zsh | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/contrib/completion/git-completion.zsh 
b/contrib/completion/git-completion.zsh
index e255413..475705a 100644
--- a/contrib/completion/git-completion.zsh
+++ b/contrib/completion/git-completion.zsh
@@ -39,7 +39,7 @@ if [ -z "$script" ]; then
test -f $e && script="$e" && break
done
 fi
-ZSH_VERSION='' . "$script"
+. "$script"
 
 __gitcomp ()
 {
-- 
2.8.0+fc1

--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 09/11] completion: zsh: fix for directories with spaces

2016-05-19 Thread Felipe Contreras
Signed-off-by: Felipe Contreras 
---
 contrib/completion/git-completion.zsh | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/contrib/completion/git-completion.zsh 
b/contrib/completion/git-completion.zsh
index 1f786cc..28eaaed 100644
--- a/contrib/completion/git-completion.zsh
+++ b/contrib/completion/git-completion.zsh
@@ -24,7 +24,7 @@ if [ -z "$script" ]; then
local -a locations
local e
locations=(
-   $(dirname ${funcsourcetrace[1]%:*})/git-completion.bash
+   "$(dirname ${funcsourcetrace[1]%:*})"/git-completion.bash
'/etc/bash_completion.d/git' # fedora, old debian
'/usr/share/bash-completion/completions/git' # arch, ubuntu, 
new debian
'/usr/share/bash-completion/git' # gentoo
-- 
2.8.0+fc1

--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 05/11] completion: remove zsh hack

2016-05-19 Thread Felipe Contreras
We don't want to override the 'complete()' function in zsh, which can be
used by bashcomp.

Reported-by: Mark Lodato 
Signed-off-by: Felipe Contreras 
---
 contrib/completion/git-completion.bash | 1 +
 contrib/completion/git-completion.zsh  | 6 --
 2 files changed, 1 insertion(+), 6 deletions(-)

diff --git a/contrib/completion/git-completion.bash 
b/contrib/completion/git-completion.bash
index 9cbae6f..6c338ae 100644
--- a/contrib/completion/git-completion.bash
+++ b/contrib/completion/git-completion.bash
@@ -2684,6 +2684,7 @@ __git_func_wrap ()
 # This is NOT a public function; use at your own risk.
 __git_complete ()
 {
+   test -n "$ZSH_VERSION" && return
local wrapper="__git_wrap${2}"
eval "$wrapper () { __git_func_wrap $2 ; }"
complete -o bashdefault -o default -o nospace -F $wrapper $1 
2>/dev/null \
diff --git a/contrib/completion/git-completion.zsh 
b/contrib/completion/git-completion.zsh
index 475705a..e10df7d 100644
--- a/contrib/completion/git-completion.zsh
+++ b/contrib/completion/git-completion.zsh
@@ -16,12 +16,6 @@
 #
 #  fpath=(~/.zsh $fpath)
 
-complete ()
-{
-   # do nothing
-   return 0
-}
-
 zstyle -T ':completion:*:*:git:*' tag-order && \
zstyle ':completion:*:*:git:*' tag-order 'common-commands'
 
-- 
2.8.0+fc1

--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 08/11] completion: zsh: improve main function selection

2016-05-19 Thread Felipe Contreras
Sometimes we want to use the function directly (e.g. _git_checkout), for
example when zsh has the option 'complete_aliases', this way, we can do
something like:

  compdef _git gco=git_checkout

Signed-off-by: Felipe Contreras 
---
 contrib/completion/git-completion.zsh | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/contrib/completion/git-completion.zsh 
b/contrib/completion/git-completion.zsh
index 317b8eb..1f786cc 100644
--- a/contrib/completion/git-completion.zsh
+++ b/contrib/completion/git-completion.zsh
@@ -204,8 +204,10 @@ _git ()
 
if (( $+functions[__${service}_zsh_main] )); then
__${service}_zsh_main
-   else
+   elif (( $+functions[__${service}_main] )); then
emulate ksh -c __${service}_main
+   elif (( $+functions[_${service}] )); then
+   emulate ksh -c _${service}
fi
 
let _ret && _default && _ret=0
-- 
2.8.0+fc1

--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC/PATCH 1/5] t5801 (remote-helpers): cleanup refspec stuff

2019-06-03 Thread Felipe Contreras
The code is much simpler this way, specially thanks to:

  git fast-export --refspec

Signed-off-by: Felipe Contreras 
---
 t/t5801-remote-helpers.sh  |  8 
 t/t5801/git-remote-testgit | 11 ---
 2 files changed, 8 insertions(+), 11 deletions(-)

diff --git a/t/t5801-remote-helpers.sh b/t/t5801-remote-helpers.sh
index d04f8007e0..48bed7c2fe 100755
--- a/t/t5801-remote-helpers.sh
+++ b/t/t5801-remote-helpers.sh
@@ -126,7 +126,7 @@ test_expect_success 'forced push' '
 '
 
 test_expect_success 'cloning without refspec' '
-   GIT_REMOTE_TESTGIT_REFSPEC="" \
+   GIT_REMOTE_TESTGIT_NOREFSPEC=1 \
git clone "testgit::${PWD}/server" local2 2>error &&
test_i18ngrep "this remote helper should implement refspec capability" 
error &&
compare_refs local2 HEAD server HEAD
@@ -135,7 +135,7 @@ test_expect_success 'cloning without refspec' '
 test_expect_success 'pulling without refspecs' '
(cd local2 &&
git reset --hard &&
-   GIT_REMOTE_TESTGIT_REFSPEC="" git pull 2>../error) &&
+   GIT_REMOTE_TESTGIT_NOREFSPEC=1 git pull 2>../error) &&
test_i18ngrep "this remote helper should implement refspec capability" 
error &&
compare_refs local2 HEAD server HEAD
 '
@@ -145,8 +145,8 @@ test_expect_success 'pushing without refspecs' '
(cd local2 &&
echo content >>file &&
git commit -a -m ten &&
-   GIT_REMOTE_TESTGIT_REFSPEC="" &&
-   export GIT_REMOTE_TESTGIT_REFSPEC &&
+   GIT_REMOTE_TESTGIT_NOREFSPEC=1 &&
+   export GIT_REMOTE_TESTGIT_NOREFSPEC &&
test_must_fail git push 2>../error) &&
test_i18ngrep "remote-helper doesn.t support push; refspec needed" error
 '
diff --git a/t/t5801/git-remote-testgit b/t/t5801/git-remote-testgit
index 752c763eb6..f2b551dfaf 100755
--- a/t/t5801/git-remote-testgit
+++ b/t/t5801/git-remote-testgit
@@ -11,13 +11,10 @@ fi
 url=$2
 
 dir="$GIT_DIR/testgit/$alias"
-prefix="refs/testgit/$alias"
 
-default_refspec="refs/heads/*:${prefix}/heads/*"
+refspec="refs/heads/*:refs/testgit/$alias/heads/*"
 
-refspec="${GIT_REMOTE_TESTGIT_REFSPEC-$default_refspec}"
-
-test -z "$refspec" && prefix="refs"
+test -n "$GIT_REMOTE_TESTGIT_NOREFSPEC" && refspec=""
 
 GIT_DIR="$url/.git"
 export GIT_DIR
@@ -81,10 +78,10 @@ do
 
echo "feature done"
git fast-export \
+   ${refspec:+"--refspec=$refspec"} \
${testgitmarks:+"--import-marks=$testgitmarks"} \
${testgitmarks:+"--export-marks=$testgitmarks"} \
-   $refs |
-   sed -e "s#refs/heads/#${prefix}/heads/#g"
+   $refs
echo "done"
;;
export)
-- 
2.21.0



[RFC/PATCH 0/5] Fix fetch regression with transport helpers

2019-06-03 Thread Felipe Contreras
I noticed a regression with running tests for git-remote-hg; can't seem to be
able to fetch tags.

Probably all remote helpers that use the import method are affected, if not
all.

The following patches are meant to test for the issue, fix it, and get some
cleanups.

I'm not exactly sure the solution is the one we want, but hopefull it gives an
idea as to what is needed.


Felipe Contreras (5):
  t5801 (remote-helpers): cleanup refspec stuff
  t5801 (remote-helpers): add test to fetch tags
  fetch: trivial cleanup
  fetch: make the code more understandable
  fetch: fix regression with transport helpers

 builtin/fetch.c| 28 ++--
 t/t5801-remote-helpers.sh  | 18 ++
 t/t5801/git-remote-testgit | 22 +-
 3 files changed, 45 insertions(+), 23 deletions(-)

-- 
2.21.0



[RFC/PATCH 3/5] fetch: trivial cleanup

2019-06-03 Thread Felipe Contreras
Create a helper function to clear an item. The way items are cleared has
changed, and will change again soon.

No functional changes.

Signed-off-by: Felipe Contreras 
---
 builtin/fetch.c | 11 ---
 1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/builtin/fetch.c b/builtin/fetch.c
index 4ba63d5ac6..8af5e319f1 100644
--- a/builtin/fetch.c
+++ b/builtin/fetch.c
@@ -287,6 +287,11 @@ static int refname_hash_exists(struct hashmap *map, const 
char *refname)
return !!hashmap_get_from_hash(map, strhash(refname), refname);
 }
 
+static void clear_item(struct refname_hash_entry *item)
+{
+   oidclr(&item->oid);
+}
+
 static void find_non_local_tags(const struct ref *refs,
struct ref **head,
struct ref ***tail)
@@ -319,7 +324,7 @@ static void find_non_local_tags(const struct ref *refs,
!will_fetch(head, ref->old_oid.hash) &&
!has_object_file_with_flags(&item->oid, 
OBJECT_INFO_QUICK) &&
!will_fetch(head, item->oid.hash))
-   oidclr(&item->oid);
+   clear_item(item);
item = NULL;
continue;
}
@@ -333,7 +338,7 @@ static void find_non_local_tags(const struct ref *refs,
if (item &&
!has_object_file_with_flags(&item->oid, OBJECT_INFO_QUICK) 
&&
!will_fetch(head, item->oid.hash))
-   oidclr(&item->oid);
+   clear_item(item);
 
item = NULL;
 
@@ -354,7 +359,7 @@ static void find_non_local_tags(const struct ref *refs,
if (item &&
!has_object_file_with_flags(&item->oid, OBJECT_INFO_QUICK) &&
!will_fetch(head, item->oid.hash))
-   oidclr(&item->oid);
+   clear_item(item);
 
/*
 * For all the tags in the remote_refs_list,
-- 
2.21.0



[RFC/PATCH 2/5] t5801 (remote-helpers): add test to fetch tags

2019-06-03 Thread Felipe Contreras
This used to work, but commit e198b3a740 broke it.

  e198b3a740 (fetch: replace string-list used as a look-up table with a hashmap)

Probably all remote helpers that use the import method are affected, but
we didn't catch the issue.

Signed-off-by: Felipe Contreras 
---
 t/t5801-remote-helpers.sh  | 10 ++
 t/t5801/git-remote-testgit | 17 -
 2 files changed, 22 insertions(+), 5 deletions(-)

diff --git a/t/t5801-remote-helpers.sh b/t/t5801-remote-helpers.sh
index 48bed7c2fe..238774bc17 100755
--- a/t/t5801-remote-helpers.sh
+++ b/t/t5801-remote-helpers.sh
@@ -303,4 +303,14 @@ test_expect_success 'fetch url' '
compare_refs server HEAD local FETCH_HEAD
 '
 
+test_expect_failure 'fetch tag' '
+   (cd server &&
+git tag v1.0
+   ) &&
+   (cd local &&
+git fetch
+   ) &&
+   compare_refs local v1.0 server v1.0
+'
+
 test_done
diff --git a/t/t5801/git-remote-testgit b/t/t5801/git-remote-testgit
index f2b551dfaf..6b9f0b5dc7 100755
--- a/t/t5801/git-remote-testgit
+++ b/t/t5801/git-remote-testgit
@@ -12,9 +12,14 @@ url=$2
 
 dir="$GIT_DIR/testgit/$alias"
 
-refspec="refs/heads/*:refs/testgit/$alias/heads/*"
+h_refspec="refs/heads/*:refs/testgit/$alias/heads/*"
+t_refspec="refs/tags/*:refs/testgit/$alias/tags/*"
 
-test -n "$GIT_REMOTE_TESTGIT_NOREFSPEC" && refspec=""
+if test -n "$GIT_REMOTE_TESTGIT_NOREFSPEC"
+then
+   h_refspec=""
+   t_refspec=""
+fi
 
 GIT_DIR="$url/.git"
 export GIT_DIR
@@ -37,7 +42,8 @@ do
capabilities)
echo 'import'
echo 'export'
-   test -n "$refspec" && echo "refspec $refspec"
+   test -n "$h_refspec" && echo "refspec $h_refspec"
+   test -n "$t_refspec" && echo "refspec $t_refspec"
if test -n "$gitmarks"
then
echo "*import-marks $gitmarks"
@@ -49,7 +55,7 @@ do
echo
;;
list)
-   git for-each-ref --format='? %(refname)' 'refs/heads/'
+   git for-each-ref --format='? %(refname)' 'refs/heads/' 
'refs/tags/'
head=$(git symbolic-ref HEAD)
echo "@$head HEAD"
echo
@@ -78,7 +84,8 @@ do
 
echo "feature done"
git fast-export \
-   ${refspec:+"--refspec=$refspec"} \
+   ${h_refspec:+"--refspec=$h_refspec"} \
+   ${t_refspec:+"--refspec=$t_refspec"} \
${testgitmarks:+"--import-marks=$testgitmarks"} \
${testgitmarks:+"--export-marks=$testgitmarks"} \
$refs
-- 
2.21.0



[RFC/PATCH 5/5] fetch: fix regression with transport helpers

2019-06-03 Thread Felipe Contreras
Commit e198b3a740 changed the behavior of fetch with regards to tags.
Before, null oids where not ignored, now they are, regardless of whether
the refs have been explicitly cleared or not.

  e198b3a740 (fetch: replace string-list used as a look-up table with a hashmap)

When using a transport helper the oids can certainly be null. So now
tags are ignored and fetching them is impossible.

This patch fixes that by having a specific flag that is set only when we
explicitly want to ignore the refs, restoring the original behavior.

Signed-off-by: Felipe Contreras 
---
 builtin/fetch.c   | 5 +++--
 t/t5801-remote-helpers.sh | 2 +-
 2 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/builtin/fetch.c b/builtin/fetch.c
index 9dc551551e..f2be50a4a3 100644
--- a/builtin/fetch.c
+++ b/builtin/fetch.c
@@ -239,6 +239,7 @@ static int will_fetch(struct ref **head, const unsigned 
char *sha1)
 struct refname_hash_entry {
struct hashmap_entry ent; /* must be the first member */
struct object_id oid;
+   int ignore;
char refname[FLEX_ARRAY];
 };
 
@@ -289,7 +290,7 @@ static int refname_hash_exists(struct hashmap *map, const 
char *refname)
 
 static void clear_item(struct refname_hash_entry *item)
 {
-   oidclr(&item->oid);
+   item->ignore = 1;
 }
 
 static void find_non_local_tags(const struct ref *refs,
@@ -374,7 +375,7 @@ static void find_non_local_tags(const struct ref *refs,
BUG("unseen remote ref?");
 
/* Unless we have already decided to ignore this item... */
-   if (is_null_oid(&item->oid))
+   if (item->ignore)
continue;
 
rm = alloc_ref(item->refname);
diff --git a/t/t5801-remote-helpers.sh b/t/t5801-remote-helpers.sh
index 238774bc17..2d6c4a281e 100755
--- a/t/t5801-remote-helpers.sh
+++ b/t/t5801-remote-helpers.sh
@@ -303,7 +303,7 @@ test_expect_success 'fetch url' '
compare_refs server HEAD local FETCH_HEAD
 '
 
-test_expect_failure 'fetch tag' '
+test_expect_success 'fetch tag' '
(cd server &&
 git tag v1.0
) &&
-- 
2.21.0



[RFC/PATCH 4/5] fetch: make the code more understandable

2019-06-03 Thread Felipe Contreras
The comment makes it seem as if the condition is the other way around.
The exception is when the oid is null, so check for that.

Signed-off-by: Felipe Contreras 
---
 builtin/fetch.c | 16 +---
 1 file changed, 9 insertions(+), 7 deletions(-)

diff --git a/builtin/fetch.c b/builtin/fetch.c
index 8af5e319f1..9dc551551e 100644
--- a/builtin/fetch.c
+++ b/builtin/fetch.c
@@ -367,19 +367,21 @@ static void find_non_local_tags(const struct ref *refs,
 */
for_each_string_list_item(remote_ref_item, &remote_refs_list) {
const char *refname = remote_ref_item->string;
+   struct ref *rm;
 
item = hashmap_get_from_hash(&remote_refs, strhash(refname), 
refname);
if (!item)
BUG("unseen remote ref?");
 
/* Unless we have already decided to ignore this item... */
-   if (!is_null_oid(&item->oid)) {
-   struct ref *rm = alloc_ref(item->refname);
-   rm->peer_ref = alloc_ref(item->refname);
-   oidcpy(&rm->old_oid, &item->oid);
-   **tail = rm;
-   *tail = &rm->next;
-   }
+   if (is_null_oid(&item->oid))
+   continue;
+
+   rm = alloc_ref(item->refname);
+   rm->peer_ref = alloc_ref(item->refname);
+   oidcpy(&rm->old_oid, &item->oid);
+   **tail = rm;
+   *tail = &rm->next;
}
hashmap_free(&remote_refs, 1);
string_list_clear(&remote_refs_list, 0);
-- 
2.21.0



Re: [RFC/PATCH 0/5] Fix fetch regression with transport helpers

2019-06-04 Thread Felipe Contreras
On Tue, Jun 4, 2019 at 9:35 AM Jeff King  wrote:
>
> On Mon, Jun 03, 2019 at 09:13:25PM -0500, Felipe Contreras wrote:

> > I'm not exactly sure the solution is the one we want, but hopefull it gives 
> > an
> > idea as to what is needed.
>
> It looks good to me. Thanks for fixing this.
>
> The breakage is in v2.20, so I don't think this needs to be rushed into
> v2.22 (which is already at -rc3). But it should probably go to 'maint'
> sooner rather than later.

Indeed, it's probably not so urgent since people have not even been
complaining (that I know of). However, I think it's clear that there's
a regression and the fix is simple, so maybe just apply the obvious
fix, and leave the rest of the patches for later?

I'm attaching only the fix, just to temp the idea of applying that
tiny thing into v2.2.

-- 
Felipe Contreras
From a59903e9828a4f265647014ca87fa3be9016a225 Mon Sep 17 00:00:00 2001
From: Felipe Contreras 
Date: Tue, 4 Jun 2019 14:10:43 -0500
Subject: [PATCH] fetch: fix regression with transport helpers

Commit e198b3a740 changed the behavior of fetch with regards to tags.
Before, null oids where not ignored, now they are, regardless of whether
the refs have been explicitly cleared or not.

  e198b3a740 (fetch: replace string-list used as a look-up table with a hashmap)

When using a transport helper the oids can certainly be null. So now
tags are ignored and fetching them is impossible.

This patch fixes that by having a specific flag that is set only when we
explicitly want to ignore the refs, restoring the original behavior.

Signed-off-by: Felipe Contreras 
---
 builtin/fetch.c | 9 +
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/builtin/fetch.c b/builtin/fetch.c
index 4ba63d5ac6..f4962b93d6 100644
--- a/builtin/fetch.c
+++ b/builtin/fetch.c
@@ -239,6 +239,7 @@ static int will_fetch(struct ref **head, const unsigned char *sha1)
 struct refname_hash_entry {
 	struct hashmap_entry ent; /* must be the first member */
 	struct object_id oid;
+	int ignore;
 	char refname[FLEX_ARRAY];
 };
 
@@ -319,7 +320,7 @@ static void find_non_local_tags(const struct ref *refs,
 			!will_fetch(head, ref->old_oid.hash) &&
 			!has_object_file_with_flags(&item->oid, OBJECT_INFO_QUICK) &&
 			!will_fetch(head, item->oid.hash))
-oidclr(&item->oid);
+item->ignore = 1;
 			item = NULL;
 			continue;
 		}
@@ -333,7 +334,7 @@ static void find_non_local_tags(const struct ref *refs,
 		if (item &&
 		!has_object_file_with_flags(&item->oid, OBJECT_INFO_QUICK) &&
 		!will_fetch(head, item->oid.hash))
-			oidclr(&item->oid);
+			item->ignore = 1;
 
 		item = NULL;
 
@@ -354,7 +355,7 @@ static void find_non_local_tags(const struct ref *refs,
 	if (item &&
 	!has_object_file_with_flags(&item->oid, OBJECT_INFO_QUICK) &&
 	!will_fetch(head, item->oid.hash))
-		oidclr(&item->oid);
+		item->ignore = 1;
 
 	/*
 	 * For all the tags in the remote_refs_list,
@@ -368,7 +369,7 @@ static void find_non_local_tags(const struct ref *refs,
 			BUG("unseen remote ref?");
 
 		/* Unless we have already decided to ignore this item... */
-		if (!is_null_oid(&item->oid)) {
+		if (!item->ignore) {
 			struct ref *rm = alloc_ref(item->refname);
 			rm->peer_ref = alloc_ref(item->refname);
 			oidcpy(&rm->old_oid, &item->oid);
-- 
2.21.0



[PATCHt2] completion: prompt: fix for Zsh

2019-06-05 Thread Felipe Contreras
We can add colour in Zsh without the need of pcmode.

Signed-off-by: Felipe Contreras 
---
 contrib/completion/git-prompt.sh | 8 +---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/contrib/completion/git-prompt.sh b/contrib/completion/git-prompt.sh
index 983e419d2b..fd2b049dbd 100644
--- a/contrib/completion/git-prompt.sh
+++ b/contrib/completion/git-prompt.sh
@@ -506,9 +506,11 @@ __git_ps1 ()
 
local z="${GIT_PS1_STATESEPARATOR-" "}"
 
-   # NO color option unless in PROMPT_COMMAND mode
-   if [ $pcmode = yes ] && [ -n "${GIT_PS1_SHOWCOLORHINTS-}" ]; then
-   __git_ps1_colorize_gitstring
+   # NO color option unless in PROMPT_COMMAND mode or it's Zsh
+   if [ -n "${GIT_PS1_SHOWCOLORHINTS-}" ]; then
+   if [ $pcmode = yes ] || [ -n "${ZSH_VERSION-}" ]; then
+   __git_ps1_colorize_gitstring
+   fi
fi
 
b=${b##refs/heads/}
-- 
2.21.0



[PATCH] completion: zsh: update installation instructions

2019-06-06 Thread Felipe Contreras
Commit 0e5ed7cca3 wrongly changed the extension of the bash script
to .zsh. The extension doesn't really matter, but it confuses people.

I've changed the text to make it clear that your zsh script goes to
~/.zsh/_git, and the bash script to ~/.git-completion.bash (or wherever
you want).

Also, update the default locations of the system bash-completion.

Signed-off-by: Felipe Contreras 
---
 contrib/completion/git-completion.zsh | 21 +++--
 1 file changed, 11 insertions(+), 10 deletions(-)

diff --git a/contrib/completion/git-completion.zsh 
b/contrib/completion/git-completion.zsh
index 886bf95d1f..b3c4588515 100644
--- a/contrib/completion/git-completion.zsh
+++ b/contrib/completion/git-completion.zsh
@@ -4,17 +4,19 @@
 #
 # Copyright (c) 2012-2013 Felipe Contreras 
 #
-# You need git's bash completion script installed somewhere, by default it
-# would be the location bash-completion uses.
-#
-# If your script is somewhere else, you can configure it on your ~/.zshrc:
-#
-#  zstyle ':completion:*:*:git:*' script ~/.git-completion.zsh
-#
 # The recommended way to install this script is to copy to '~/.zsh/_git', and
 # then add the following to your ~/.zshrc file:
 #
 #  fpath=(~/.zsh $fpath)
+#
+# You need git's bash completion script installed. By default bash-completion
+# uses /usr/share/bash-completion.
+#
+# If your bash completion script is somewhere else, you can configure it on
+# your ~/.zshrc:
+#
+#  zstyle ':completion:*:*:git:*' script ~/.git-completion.bash
+#
 
 complete ()
 {
@@ -31,9 +33,8 @@ if [ -z "$script" ]; then
local e
locations=(
$(dirname ${funcsourcetrace[1]%:*})/git-completion.bash
-   '/etc/bash_completion.d/git' # fedora, old debian
-   '/usr/share/bash-completion/completions/git' # arch, ubuntu, 
new debian
-   '/usr/share/bash-completion/git' # gentoo
+   '/usr/share/bash-completion/completions/git'
+   '/etc/bash_completion.d/git' # old debian
)
for e in $locations; do
test -f $e && script="$e" && break
-- 
2.21.0



Re: [PATCH] completion (zsh): fix misleading install location

2019-06-06 Thread Felipe Contreras
On Thu, Jun 6, 2019 at 5:37 PM Durant Schoon  wrote:

> diff --git a/contrib/completion/git-completion.zsh 
> b/contrib/completion/git-completion.zsh
> index 886bf95d1f594..0e63004e2613e 100644
> --- a/contrib/completion/git-completion.zsh
> +++ b/contrib/completion/git-completion.zsh
> @@ -11,8 +11,8 @@
>  #
>  #  zstyle ':completion:*:*:git:*' script ~/.git-completion.zsh
>  #
> -# The recommended way to install this script is to copy to '~/.zsh/_git', and
> -# then add the following to your ~/.zshrc file:
> +# The recommended way to install this script is to copy to '~/.zsh/_git/',
> +# and then add the following to your ~/.zshrc file:

~/.zsh/_git should be a file, not a directory.

-- 
Felipe Contreras


[PATCH] test: completion: tests for __gitcomp regression

2019-06-06 Thread Felipe Contreras
There's a regression in the completion since the introduction of
__gitcomp.

Go to any directory that doesn't contain a git repository, like /tmp.
Then type the following:

  git checkout --

You will see nothing. That's because
`git checkout --git-completion-helper` fails when you run it outside a
git repository.

You might change to a directory that has a git repository, but it's too
late, because the empty options have been cached.

It's unclear how many commands are affected, but this patch attempts to
at least detect some already in the testing framework.

Signed-off-by: Felipe Contreras 
---
 t/t9902-completion.sh | 33 ++---
 1 file changed, 26 insertions(+), 7 deletions(-)

diff --git a/t/t9902-completion.sh b/t/t9902-completion.sh
index 43cf313a1c..1319c542e1 100755
--- a/t/t9902-completion.sh
+++ b/t/t9902-completion.sh
@@ -122,6 +122,15 @@ test_gitcomp_nl ()
test_cmp expected out
 }
 
+offgit ()
+{
+   GIT_CEILING_DIRECTORIES="$ROOT" &&
+   export GIT_CEILING_DIRECTORIES &&
+   test_when_finished "ROOT='$ROOT'; cd '$TRASH_DIRECTORY'; unset 
GIT_CEILING_DIRECTORIES" &&
+   ROOT="$ROOT"/non-repo &&
+   cd "$ROOT"
+}
+
 invalid_variable_name='${foo.bar}'
 
 actual="$TRASH_DIRECTORY/actual"
@@ -358,10 +367,8 @@ test_expect_success SYMLINKS '__git_find_repo_path - 
resulting path avoids symli
 '
 
 test_expect_success '__git_find_repo_path - not a git repository' '
+   offgit &&
(
-   cd non-repo &&
-   GIT_CEILING_DIRECTORIES="$ROOT" &&
-   export GIT_CEILING_DIRECTORIES &&
test_must_fail __git_find_repo_path &&
printf "$__git_repo_path" >"$actual"
) &&
@@ -1388,6 +1395,7 @@ test_expect_success '__git_pretty_aliases' '
 '
 
 test_expect_success 'basic' '
+   offgit &&
run_completion "git " &&
# built-in
grep -q "^add \$" out &&
@@ -1401,6 +1409,7 @@ test_expect_success 'basic' '
 '
 
 test_expect_success 'double dash "git" itself' '
+   offgit &&
test_completion "git --" <<-\EOF
--paginate Z
--no-pager Z
@@ -1419,7 +1428,8 @@ test_expect_success 'double dash "git" itself' '
EOF
 '
 
-test_expect_success 'double dash "git checkout"' '
+test_expect_failure 'double dash "git checkout"' '
+   offgit &&
test_completion "git checkout --" <<-\EOF
--quiet Z
--detach Z
@@ -1442,6 +1452,7 @@ test_expect_success 'double dash "git checkout"' '
 '
 
 test_expect_success 'general options' '
+   offgit &&
test_completion "git --ver" "--version " &&
test_completion "git --hel" "--help " &&
test_completion "git --exe" <<-\EOF &&
@@ -1460,6 +1471,7 @@ test_expect_success 'general options' '
 '
 
 test_expect_success 'general options plus command' '
+   offgit &&
test_completion "git --version check" "checkout " &&
test_completion "git --paginate check" "checkout " &&
test_completion "git --git-dir=foo check" "checkout " &&
@@ -1480,11 +1492,13 @@ test_expect_success 'general options plus command' '
 '
 
 test_expect_success 'git --help completion' '
+   offgit &&
test_completion "git --help ad" "add " &&
test_completion "git --help core" "core-tutorial "
 '
 
-test_expect_success 'completion.commands removes multiple commands' '
+test_expect_failure 'completion.commands removes multiple commands' '
+   offgit &&
test_config completion.commands "-cherry -mergetool" &&
git --list-cmds=list-mainporcelain,list-complete,config >out &&
! grep -E "^(cherry|mergetool)$" out
@@ -1547,7 +1561,8 @@ test_expect_success 'complete tree filename with 
metacharacters' '
EOF
 '
 
-test_expect_success PERL 'send-email' '
+test_expect_failure PERL 'send-email' '
+   offgit &&
test_completion "git send-email --cov" "--cover-letter " &&
test_completion "git send-email ma" "master "
 '
@@ -1649,6 +1664,7 @@ test_expect_success 'completion used  completion for 
alias: !f() { : git 

Re: [PATCH] completion: do not cache if --git-completion-helper fails

2019-06-07 Thread Felipe Contreras
On Fri, Jun 7, 2019 at 5:02 AM SZEDER Gábor  wrote:
>
> On Fri, Jun 07, 2019 at 04:30:34PM +0700, Nguyễn Thái Ngọc Duy wrote:
> > "git  --git-completion-helper" could fail if the command checks for
> > a repo before parse_options(). If the result is cached, later on when
> > the user moves to a worktree with repo, tab completion will still fail.
> >
> > Avoid this by detecting errors and not cache the completion output. We
> > can try again and hopefully succeed next time (e.g. when a repo is
> > found).
> >
> > Of course if --git-completion-helper fails permanently because of other
> > reasons (*), this will slow down completion. But I don't see any better
> > option to handle that case.
>
> I think a permanently failing 'git cmd --git-completion-helper'
> shouldn't really happen, unless there is a bug in the completion
> script or the git installation or similar exceptional situation.  And
> then that issue should be fixed, but I don't think we should worry
> about an extra subshell and git process in those situations.

Indeed. In think there's only sane option to make this work in all
situation; a reorganization.

Something like this should work:

struct command checkout_command = {
.name = "checkout",
.function = cmd_checkout,
.run_options = RUN_SETUP | NEED_WORK_TREE,
.help = N_("Switch branches or restore working tree files"),
.options = {
OPT__QUIET(&opts.quiet, N_("suppress progress reporting")),
...
},
}

This way we could run parse_options_show_gitcomp() from git.c and not
worry about whatever cmd_checkout() needs.

This has the added advantage that it gathers information about this
command that is stray in multiple sources (git.c, command-list.h), and
it makes builtin.h cleaner too.

Plus, we could rework the way -h works too.

-- 
Felipe Contreras


Re: [PATCH] completion: do not cache if --git-completion-helper fails

2019-06-13 Thread Felipe Contreras
On Wed, Jun 12, 2019 at 3:52 AM Duy Nguyen  wrote:
>
> On Sat, Jun 8, 2019 at 12:33 AM Felipe Contreras
>  wrote:

> > Something like this should work:
> >
> > struct command checkout_command = {
> > .name = "checkout",
> > .function = cmd_checkout,
> > .run_options = RUN_SETUP | NEED_WORK_TREE,
> > .help = N_("Switch branches or restore working tree files"),
> > .options = {
> > OPT__QUIET(&opts.quiet, N_("suppress progress reporting")),
> > ...
> > },
> > }
> >
> > This way we could run parse_options_show_gitcomp() from git.c and not
> > worry about whatever cmd_checkout() needs.
>
> This only works for a few commands. Those with subcommands already
> have struct option[] array scattered in different places. And some new
> ones also have struct option array dynamically created.
>
> It's not impossible to do. But I feel there's a lot of reorganizing
> for little gain. Maybe when we pass 'struct repository *' to all
> commands, which means we hit all commmands at once anyway, we can
> reconsider this (and having config parser in a more declarative form
> like cmd option parser).

Well yes, there is little *functional* gain at the moment, but this
(or some version of this) must be done eventually.

For the moment we still have an issue, but I see there's already a
hack present for '-h', maybe we can re-utilize it. Something like
this:

--- a/git.c
+++ b/git.c
@@ -408,6 +408,8 @@ static int run_builtin(struct cmd_struct *p, int
argc, const char **argv)

prefix = NULL;
help = argc == 2 && !strcmp(argv[1], "-h");
+   if (!help)
+   help = argc == 2 && !strcmp(argv[1], "--git-completion-helper");
if (!help) {
    if (p->option & RUN_SETUP)
prefix = setup_git_directory();

One way or the other, shouldn't my tests be merged? The issue is still
there, and it's nice to have tests for that.

-- 
Felipe Contreras


Re: [PATCH] completion: do not cache if --git-completion-helper fails

2019-06-13 Thread Felipe Contreras
On Thu, Jun 13, 2019 at 9:53 PM Duy Nguyen  wrote:
>
> On Fri, Jun 14, 2019 at 7:30 AM Felipe Contreras
>  wrote:

> > One way or the other, shouldn't my tests be merged? The issue is still
> > there, and it's nice to have tests for that.
>
> Is there any good reason to complete options when they are not going
> to work anyway (e.g. like checkout which needs $GIT_DIR)? Besides "it
> used to work before --git-completion-helper" which I don't consider a
> good reason given the maintenance tradeoff of --git-completion-helper.

No, there is no good reason that I can think of, except checking the
arguments, which is precisely how I found out the issue; not something
I usually do. But a newcomer might not know what commands don't work
outside a git directory.

But more importantly; is there a good enough reason not to? I seem to
recall to be annoyed by the fact that 'git command -h' failed on some
command with a fatal error. Similarly, I don't see any good reason why
'git help clone' should ever fail.

These are not dealbreakers by any means, just some kind of weird
corner cases. Such things never happen in in Mercurial BTW.

And of course --git-completion-helper is the way to go, I recall I
wanted to implement such a thing myself, this has the potential to
increase the power of the zsh completion incredibly, although not yet.

But that doesn't mean it's perfect and there are no regressions; there
are. I just think they should be documented in the testing framework.
They are not big enough to warrant going back from
--git-completion-helper though.

The only real issue I think has not been raised is that the completion
scripts are in "contrib", they are not considered part of the main
deliverables. So it's conceivable that somebody running Git v1.6 tries
the completion scripts of v1.20, and everything breaks. I'm still not
exactly sure what should be the way to solve this conundrum, but
again, I don't think going back from --git-completion-helper is a good
move. I don't think I suggested that.

Cheers.

-- 
Felipe Contreras


[PATCH 5/5] completion: prompt: fix color for Zsh

2019-06-13 Thread Felipe Contreras
We don't need PROMPT_COMMAND in Zsh; we are already using %F{color} %f,
which in turn use %{ and %}, which are the equivalent of Bash's
\[ and \].

We can use as many colors as we want and output directly into PS1
(or RPS1) without the risk of buffer wrapping issues.

Signed-off-by: Felipe Contreras 
---
 contrib/completion/git-prompt.sh | 10 ++
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/contrib/completion/git-prompt.sh b/contrib/completion/git-prompt.sh
index 983e419d2b..b57a9c96cb 100644
--- a/contrib/completion/git-prompt.sh
+++ b/contrib/completion/git-prompt.sh
@@ -88,7 +88,7 @@
 # If you would like a colored hint about the current dirty state, set
 # GIT_PS1_SHOWCOLORHINTS to a nonempty value. The colors are based on
 # the colored output of "git status -sb" and are available only when
-# using __git_ps1 for PROMPT_COMMAND or precmd.
+# using __git_ps1 for PROMPT_COMMAND in Bash, but always available in Zsh.
 #
 # If you would like __git_ps1 to do nothing in the case when the current
 # directory is set up to be ignored by git, then set
@@ -506,9 +506,11 @@ __git_ps1 ()
 
local z="${GIT_PS1_STATESEPARATOR-" "}"
 
-   # NO color option unless in PROMPT_COMMAND mode
-   if [ $pcmode = yes ] && [ -n "${GIT_PS1_SHOWCOLORHINTS-}" ]; then
-   __git_ps1_colorize_gitstring
+   # NO color option unless in PROMPT_COMMAND mode or it's Zsh
+   if [ -n "${GIT_PS1_SHOWCOLORHINTS-}" ]; then
+   if [ $pcmode = yes ] || [ -n "${ZSH_VERSION-}" ]; then
+   __git_ps1_colorize_gitstring
+   fi
fi
 
b=${b##refs/heads/}
-- 
2.22.0.rc2.dirty



[PATCH 1/5] completion: zsh: update installation instructions

2019-06-13 Thread Felipe Contreras
Commit 0e5ed7cca3 wrongly changed the extension of the bash script
to .zsh. The extension doesn't really matter, but it confuses people.

I've changed the text to make it clear that your zsh script goes to
~/.zsh/_git, and the bash script to ~/.git-completion.bash (or wherever
you want).

Also, update the default locations of the system bash-completion.

Signed-off-by: Felipe Contreras 
---
 contrib/completion/git-completion.zsh | 21 +++--
 1 file changed, 11 insertions(+), 10 deletions(-)

diff --git a/contrib/completion/git-completion.zsh 
b/contrib/completion/git-completion.zsh
index 886bf95d1f..b3c4588515 100644
--- a/contrib/completion/git-completion.zsh
+++ b/contrib/completion/git-completion.zsh
@@ -4,17 +4,19 @@
 #
 # Copyright (c) 2012-2013 Felipe Contreras 
 #
-# You need git's bash completion script installed somewhere, by default it
-# would be the location bash-completion uses.
-#
-# If your script is somewhere else, you can configure it on your ~/.zshrc:
-#
-#  zstyle ':completion:*:*:git:*' script ~/.git-completion.zsh
-#
 # The recommended way to install this script is to copy to '~/.zsh/_git', and
 # then add the following to your ~/.zshrc file:
 #
 #  fpath=(~/.zsh $fpath)
+#
+# You need git's bash completion script installed. By default bash-completion
+# uses /usr/share/bash-completion.
+#
+# If your bash completion script is somewhere else, you can configure it on
+# your ~/.zshrc:
+#
+#  zstyle ':completion:*:*:git:*' script ~/.git-completion.bash
+#
 
 complete ()
 {
@@ -31,9 +33,8 @@ if [ -z "$script" ]; then
local e
locations=(
$(dirname ${funcsourcetrace[1]%:*})/git-completion.bash
-   '/etc/bash_completion.d/git' # fedora, old debian
-   '/usr/share/bash-completion/completions/git' # arch, ubuntu, 
new debian
-   '/usr/share/bash-completion/git' # gentoo
+   '/usr/share/bash-completion/completions/git'
+   '/etc/bash_completion.d/git' # old debian
)
for e in $locations; do
test -f $e && script="$e" && break
-- 
2.22.0.rc2.dirty



[PATCH 4/5] completion: zsh: improve main function selection

2019-06-13 Thread Felipe Contreras
Sometimes we want to use the function directly (e.g. _git_checkout), for
example when zsh has the option 'complete_aliases', this way, we can do
something like:

  compdef _git gco=git_checkout

Signed-off-by: Felipe Contreras 
---
 contrib/completion/git-completion.zsh | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/contrib/completion/git-completion.zsh 
b/contrib/completion/git-completion.zsh
index 58b3b5c27d..92b956d5de 100644
--- a/contrib/completion/git-completion.zsh
+++ b/contrib/completion/git-completion.zsh
@@ -227,8 +227,10 @@ _git ()
 
if (( $+functions[__${service}_zsh_main] )); then
__${service}_zsh_main
-   else
+   elif (( $+functions[__${service}_main] )); then
emulate ksh -c __${service}_main
+   elif (( $+functions[_${service}] )); then
+   emulate ksh -c _${service}
fi
 
let _ret && _default && _ret=0
-- 
2.22.0.rc2.dirty



[PATCH 0/5] contrib: completion: general zsh updates

2019-06-13 Thread Felipe Contreras
Helo,

These patches are definitely needed, and some of these have been cooking
for years in oh-my-zsh.

Felipe Contreras (5):
  completion: zsh: update installation instructions
  completion: zsh: fix for directories with spaces
  completion: remove zsh hack
  completion: zsh: improve main function selection
  completion: prompt: fix color for Zsh

 contrib/completion/git-completion.bash |  1 +
 contrib/completion/git-completion.zsh  | 33 --
 contrib/completion/git-prompt.sh   | 10 
 3 files changed, 22 insertions(+), 22 deletions(-)

-- 
2.22.0.rc2.dirty



[PATCH 2/5] completion: zsh: fix for directories with spaces

2019-06-13 Thread Felipe Contreras
Signed-off-by: Felipe Contreras 
---
 contrib/completion/git-completion.zsh | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/contrib/completion/git-completion.zsh 
b/contrib/completion/git-completion.zsh
index b3c4588515..067738d93f 100644
--- a/contrib/completion/git-completion.zsh
+++ b/contrib/completion/git-completion.zsh
@@ -32,7 +32,7 @@ if [ -z "$script" ]; then
local -a locations
local e
locations=(
-   $(dirname ${funcsourcetrace[1]%:*})/git-completion.bash
+   "$(dirname ${funcsourcetrace[1]%:*})"/git-completion.bash
'/usr/share/bash-completion/completions/git'
'/etc/bash_completion.d/git' # old debian
)
-- 
2.22.0.rc2.dirty



[PATCH 3/5] completion: remove zsh hack

2019-06-13 Thread Felipe Contreras
We don't want to override the 'complete()' function in zsh, which can be
used by bashcomp.

Reported-by: Mark Lodato 
Signed-off-by: Felipe Contreras 
---
 contrib/completion/git-completion.bash | 1 +
 contrib/completion/git-completion.zsh  | 6 --
 2 files changed, 1 insertion(+), 6 deletions(-)

diff --git a/contrib/completion/git-completion.bash 
b/contrib/completion/git-completion.bash
index 9f71bcde96..57cced3f51 100644
--- a/contrib/completion/git-completion.bash
+++ b/contrib/completion/git-completion.bash
@@ -3066,6 +3066,7 @@ __git_func_wrap ()
 # This is NOT a public function; use at your own risk.
 __git_complete ()
 {
+   test -n "$ZSH_VERSION" && return
local wrapper="__git_wrap${2}"
eval "$wrapper () { __git_func_wrap $2 ; }"
complete -o bashdefault -o default -o nospace -F $wrapper $1 
2>/dev/null \
diff --git a/contrib/completion/git-completion.zsh 
b/contrib/completion/git-completion.zsh
index 067738d93f..58b3b5c27d 100644
--- a/contrib/completion/git-completion.zsh
+++ b/contrib/completion/git-completion.zsh
@@ -18,12 +18,6 @@
 #  zstyle ':completion:*:*:git:*' script ~/.git-completion.bash
 #
 
-complete ()
-{
-   # do nothing
-   return 0
-}
-
 zstyle -T ':completion:*:*:git:*' tag-order && \
zstyle ':completion:*:*:git:*' tag-order 'common-commands'
 
-- 
2.22.0.rc2.dirty



[PATCH 09/14] completion: bash: remove zsh wrapper

2019-06-21 Thread Felipe Contreras
It has been deprecated for more than seven years. It's time to move on.

Signed-off-by: Felipe Contreras 
---
 contrib/completion/git-completion.bash | 84 +-
 1 file changed, 2 insertions(+), 82 deletions(-)

diff --git a/contrib/completion/git-completion.bash 
b/contrib/completion/git-completion.bash
index 1f9b833913..d3ee6c7dc2 100644
--- a/contrib/completion/git-completion.bash
+++ b/contrib/completion/git-completion.bash
@@ -2969,88 +2969,8 @@ __gitk_main ()
__git_complete_revlist
 }
 
-if [[ -n ${ZSH_VERSION-} ]] &&
-   # Don't define these functions when sourced from 'git-completion.zsh',
-   # it has its own implementations.
-   [[ -z ${GIT_SOURCING_ZSH_COMPLETION-} ]]; then
-   echo "WARNING: this script is deprecated, please see 
git-completion.zsh" 1>&2
-
-   autoload -U +X compinit && compinit
-
-   __gitcomp ()
-   {
-   emulate -L zsh
-
-   local cur_="${3-$cur}"
-
-   case "$cur_" in
-   --*=)
-   ;;
-   *)
-   local c IFS=$' \t\n'
-   local -a array
-   for c in ${=1}; do
-   c="$c${4-}"
-   case $c in
-   --*=*|*.) ;;
-   *) c="$c " ;;
-   esac
-   array[${#array[@]}+1]="$c"
-   done
-   compset -P '*[=:]'
-   compadd -Q -S '' -p "${2-}" -a -- array && _ret=0
-   ;;
-   esac
-   }
-
-   __gitcomp_direct ()
-   {
-   emulate -L zsh
-
-   local IFS=$'\n'
-   compset -P '*[=:]'
-   compadd -Q -- ${${=1}% } && _ret=0
-   }
-
-   __gitcomp_nl ()
-   {
-   emulate -L zsh
-
-   local IFS=$'\n'
-   compset -P '*[=:]'
-   compadd -Q -S "${4- }" -p "${2-}" -- ${=1} && _ret=0
-   }
-
-   __gitcomp_file_direct ()
-   {
-   emulate -L zsh
-
-   local IFS=$'\n'
-   compset -P '*[=:]'
-   compadd -f -- ${=1} && _ret=0
-   }
-
-   __gitcomp_file ()
-   {
-   emulate -L zsh
-
-   local IFS=$'\n'
-   compset -P '*[=:]'
-   compadd -p "${2-}" -f -- ${=1} && _ret=0
-   }
-
-   _git ()
-   {
-   local _ret=1 cur cword prev
-   cur=${words[CURRENT]}
-   prev=${words[CURRENT-1]}
-   let cword=CURRENT-1
-   emulate ksh -c __${service}_main
-   let _ret && _default && _ret=0
-   return _ret
-   }
-
-   compdef _git git gitk
+if [[ -n ${ZSH_VERSION-} && -z ${GIT_SOURCING_ZSH_COMPLETION-} ]]; then
+   echo "ERROR: this script is obsolete, please see git-completion.zsh" 
1>&2
return
 fi
 
-- 
2.22.0



[PATCH 07/14] completion: zsh: update installation instructions

2019-06-21 Thread Felipe Contreras
Commit 0e5ed7cca3 wrongly changed the extension of the bash script
to .zsh. The extension doesn't really matter, but it confuses people.

I've changed the text to make it clear that your zsh script goes to
~/.zsh/_git, and the bash script to ~/.contrib/completion/git-completion.bash 
(or wherever
you want).

Also, update the default locations of the system bash-completion,
including the default bash-completion location for user scripts, and the
recommended way to find the system location (with pkg-config)

Signed-off-by: Felipe Contreras 
---
 contrib/completion/git-completion.zsh | 23 +--
 1 file changed, 13 insertions(+), 10 deletions(-)

diff --git a/contrib/completion/git-completion.zsh 
b/contrib/completion/git-completion.zsh
index 2801f2f7c8..7f614d5854 100644
--- a/contrib/completion/git-completion.zsh
+++ b/contrib/completion/git-completion.zsh
@@ -4,17 +4,19 @@
 #
 # Copyright (c) 2012-2013 Felipe Contreras 
 #
-# You need git's bash completion script installed somewhere, by default it
-# would be the location bash-completion uses.
-#
-# If your script is somewhere else, you can configure it on your ~/.zshrc:
-#
-#  zstyle ':completion:*:*:git:*' script ~/.git-completion.zsh
-#
 # The recommended way to install this script is to copy to '~/.zsh/_git', and
 # then add the following to your ~/.zshrc file:
 #
 #  fpath=(~/.zsh $fpath)
+#
+# You need git's bash completion script installed. By default it will use
+# bash-completion's script.
+#
+# If your bash completion script is somewhere else, you can configure it on
+# your ~/.zshrc:
+#
+#  zstyle ':completion:*:*:git:*' script ~/.git-completion.bash
+#
 
 zstyle -T ':completion:*:*:git:*' tag-order && \
zstyle ':completion:*:*:git:*' tag-order 'common-commands'
@@ -25,9 +27,10 @@ if [ -z "$script" ]; then
local e
locations=(
"$(dirname ${funcsourcetrace[1]%:*})"/git-completion.bash
-   '/etc/bash_completion.d/git' # fedora, old debian
-   '/usr/share/bash-completion/completions/git' # arch, ubuntu, 
new debian
-   '/usr/share/bash-completion/git' # gentoo
+   "$HOME/.local/share/bash-completion/completions/git"
+   "$(pkg-config --variable=completionsdir bash-completion)"/git
+   '/usr/share/bash-completion/completions/git'
+   '/etc/bash_completion.d/git' # old debian
)
for e in $locations; do
test -f $e && script="$e" && break
-- 
2.22.0



[PATCH 06/14] completion: bash: cleanup cygwin check

2019-06-21 Thread Felipe Contreras
Avoid Yoda conditions, and use $OSTYPE.

Signed-off-by: Felipe Contreras 
---
 contrib/completion/git-completion.bash | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/contrib/completion/git-completion.bash 
b/contrib/completion/git-completion.bash
index 676b19a983..dba822d0e7 100644
--- a/contrib/completion/git-completion.bash
+++ b/contrib/completion/git-completion.bash
@@ -3092,6 +3092,6 @@ __git_complete gitk __gitk_main
 # when the user has tab-completed the executable name and consequently
 # included the '.exe' suffix.
 #
-if [ Cygwin = "$(uname -o 2>/dev/null)" ]; then
-__git_complete git.exe __git_main
+if [ "$OSTYPE" = "Cygwin" ]; then
+   __git_complete git.exe __git_main
 fi
-- 
2.22.0



[PATCH 13/14] completion: add default options

2019-06-21 Thread Felipe Contreras
Versions of Git older than v2.17 don't know about
--git-completion-helper, so provide some defaults for them.

Also, some commands fail if there's no Git repository available.

Signed-off-by: Felipe Contreras 
---
 contrib/completion/git-completion.bash | 97 +-
 t/t9902-completion.sh  |  4 +-
 2 files changed, 98 insertions(+), 3 deletions(-)

diff --git a/contrib/completion/git-completion.bash 
b/contrib/completion/git-completion.bash
index d3ee6c7dc2..922ba5f925 100644
--- a/contrib/completion/git-completion.bash
+++ b/contrib/completion/git-completion.bash
@@ -377,6 +377,100 @@ else
unset $(compgen -v __gitcomp_builtin_)
 fi
 
+__gitcomp_builtin_add_default=" --dry-run --verbose --interactive --patch 
--edit --force --update --renormalize --intent-to-add --all --ignore-removal 
--refresh --ignore-errors --ignore-missing --chmod= --no-dry-run -- 
--no-verbose --no-interactive --no-patch --no-edit --no-force --no-update 
--no-renormalize --no-intent-to-add --no-all --no-ignore-removal --no-refresh 
--no-ignore-errors --no-ignore-missing --no-chmod"
+__gitcomp_builtin_am_default=" --interactive --3way --quiet --signoff --utf8 
--keep --keep-non-patch --message-id --keep-cr --no-keep-cr --scissors 
--whitespace= --ignore-space-change --ignore-whitespace --directory= --exclude= 
--include= --patch-format= --reject --resolvemsg= --continue --resolved --skip 
--abort --quit --show-current-patch --committer-date-is-author-date 
--ignore-date --rerere-autoupdate --gpg-sign -- --no-interactive --no-3way 
--no-quiet --no-signoff --no-utf8 --no-keep --no-keep-non-patch --no-message-id 
--no-scissors --no-whitespace --no-ignore-space-change --no-ignore-whitespace 
--no-directory --no-exclude --no-include --no-patch-format --no-reject 
--no-resolvemsg --no-committer-date-is-author-date --no-ignore-date 
--no-rerere-autoupdate --no-gpg-sign"
+__gitcomp_builtin_apply_default=" --exclude= --include= --no-add --stat 
--numstat --summary --check --index --intent-to-add --cached --apply --3way 
--build-fake-ancestor= --whitespace= --ignore-space-change --ignore-whitespace 
--reverse --unidiff-zero --reject --allow-overlap --verbose --inaccurate-eof 
--recount --directory= --add -- --no-stat --no-numstat --no-summary --no-check 
--no-index --no-intent-to-add --no-cached --no-apply --no-3way 
--no-build-fake-ancestor --no-whitespace --no-ignore-space-change 
--no-ignore-whitespace --no-reverse --no-unidiff-zero --no-reject 
--no-allow-overlap --no-verbose --no-inaccurate-eof --no-recount --no-directory"
+__gitcomp_builtin_archive_default=" --output= --remote= --exec= --no-output -- 
--no-remote --no-exec"
+__gitcomp_builtin_bisect__helper_default=" --next-all --write-terms 
--bisect-clean-state --check-expected-revs --bisect-reset --bisect-write 
--check-and-set-terms --bisect-next-check --bisect-terms --bisect-start 
--no-checkout --no-log --checkout --log"
+__gitcomp_builtin_blame_default=" --incremental --root --show-stats --progress 
--score-debug --show-name --show-number --porcelain --line-porcelain 
--show-email --color-lines --color-by-age --indent-heuristic --minimal 
--contents= --abbrev --no-incremental -- --no-root --no-show-stats 
--no-progress --no-score-debug --no-show-name --no-show-number --no-porcelain 
--no-line-porcelain --no-show-email --no-color-lines --no-color-by-age 
--no-minimal --no-contents --no-abbrev"
+__gitcomp_builtin_branch_default=" --verbose --quiet --track 
--set-upstream-to= --unset-upstream --color --remotes --contains --no-contains 
--abbrev --all --delete --move --copy --list --show-current --create-reflog 
--edit-description --merged --no-merged --column --sort= --points-at= 
--ignore-case --format= -- --no-verbose --no-quiet --no-track 
--no-set-upstream-to --no-unset-upstream --no-color --no-remotes --no-abbrev 
--no-all --no-delete --no-move --no-copy --no-list --no-show-current 
--no-create-reflog --no-edit-description --no-column --no-points-at 
--no-ignore-case --no-format"
+__gitcomp_builtin_cat_file_default=" --textconv --filters --path= 
--allow-unknown-type --buffer --batch --batch-check --follow-symlinks 
--batch-all-objects --unordered --no-path -- --no-allow-unknown-type 
--no-buffer --no-follow-symlinks --no-batch-all-objects --no-unordered"
+__gitcomp_builtin_check_attr_default=" --all --cached --stdin --no-all -- 
--no-cached --no-stdin"
+__gitcomp_builtin_check_ignore_default=" --quiet --verbose --stdin 
--non-matching --no-index --index -- --no-quiet --no-verbose --no-stdin 
--no-non-matching"
+__gitcomp_builtin_check_mailmap_default=" --stdin --no-stdin"
+__gitcomp_builtin_checkout_default=" --quiet --detach --track --orphan= --ours 
--theirs --merge --conflict= --patch --ignore-skip-worktree-bits --no-guess 
--ignore-other-worktrees --recurse-submodules --progress --overlay --guess -- 
--no-q

[PATCH 12/14] test: completion: use global config

2019-06-21 Thread Felipe Contreras
When appropriate.

Signed-off-by: Felipe Contreras 
---
 t/t9902-completion.sh | 10 +-
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/t/t9902-completion.sh b/t/t9902-completion.sh
index 7bef41eaf5..3dbfef6960 100755
--- a/t/t9902-completion.sh
+++ b/t/t9902-completion.sh
@@ -1497,9 +1497,9 @@ test_expect_success 'git --help completion' '
test_completion "git --help core" "core-tutorial "
 '
 
-test_expect_failure 'completion.commands removes multiple commands' '
+test_expect_success 'completion.commands removes multiple commands' '
offgit &&
-   test_config completion.commands "-cherry -mergetool" &&
+   test_config_global completion.commands "-cherry -mergetool" &&
git --list-cmds=list-mainporcelain,list-complete,config >out &&
! grep -E "^(cherry|mergetool)$" out
 '
@@ -1637,7 +1637,7 @@ test_expect_success 'complete files' '
 '
 
 test_expect_success "completion uses  completion for alias: !sh -c 'git 
 ...'" '
-   test_config alias.co "!sh -c '"'"'git checkout ...'"'"'" &&
+   test_config_global alias.co "!sh -c '"'"'git checkout ...'"'"'" &&
test_completion "git co m" <<-\EOF
master Z
mybranch Z
@@ -1646,7 +1646,7 @@ test_expect_success "completion uses  completion for 
alias: !sh -c 'git  completion for alias: !f () { 
VAR=val git  ... }' '
-   test_config alias.co "!f () { VAR=val git checkout ... ; } f" &&
+   test_config_global alias.co "!f () { VAR=val git checkout ... ; } f" &&
test_completion "git co m" <<-\EOF
master Z
mybranch Z
@@ -1655,7 +1655,7 @@ test_expect_success 'completion uses  completion for 
alias: !f () { VAR=val
 '
 
 test_expect_success 'completion used  completion for alias: !f() { : git 
 ; ... }' '
-   test_config alias.co "!f() { : git checkout ; if ... } f" &&
+   test_config_global alias.co "!f() { : git checkout ; if ... } f" &&
test_completion "git co m" <<-\EOF
master Z
mybranch Z
-- 
2.22.0



[PATCH 05/14] completion: prompt: fix color for Zsh

2019-06-21 Thread Felipe Contreras
We don't need PROMPT_COMMAND in Zsh; we are already using %F{color} %f,
which in turn use %{ and %}, which are the equivalent of Bash's
\[ and \].

We can use as many colors as we want and output directly into PS1
(or RPS1) without the risk of buffer wrapping issues.

Signed-off-by: Felipe Contreras 
---
 contrib/completion/git-prompt.sh | 10 ++
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/contrib/completion/git-prompt.sh b/contrib/completion/git-prompt.sh
index 983e419d2b..b57a9c96cb 100644
--- a/contrib/completion/git-prompt.sh
+++ b/contrib/completion/git-prompt.sh
@@ -88,7 +88,7 @@
 # If you would like a colored hint about the current dirty state, set
 # GIT_PS1_SHOWCOLORHINTS to a nonempty value. The colors are based on
 # the colored output of "git status -sb" and are available only when
-# using __git_ps1 for PROMPT_COMMAND or precmd.
+# using __git_ps1 for PROMPT_COMMAND in Bash, but always available in Zsh.
 #
 # If you would like __git_ps1 to do nothing in the case when the current
 # directory is set up to be ignored by git, then set
@@ -506,9 +506,11 @@ __git_ps1 ()
 
local z="${GIT_PS1_STATESEPARATOR-" "}"
 
-   # NO color option unless in PROMPT_COMMAND mode
-   if [ $pcmode = yes ] && [ -n "${GIT_PS1_SHOWCOLORHINTS-}" ]; then
-   __git_ps1_colorize_gitstring
+   # NO color option unless in PROMPT_COMMAND mode or it's Zsh
+   if [ -n "${GIT_PS1_SHOWCOLORHINTS-}" ]; then
+   if [ $pcmode = yes ] || [ -n "${ZSH_VERSION-}" ]; then
+   __git_ps1_colorize_gitstring
+   fi
fi
 
b=${b##refs/heads/}
-- 
2.22.0



[PATCH 00/14] completion: a bunch of updates

2019-06-21 Thread Felipe Contreras
Hi,

Here's another try at completion fixes, cleanups, and more tests. Some
of these have already been sent.

Felipe Contreras (14):
  completion: zsh: fix __gitcomp_direct()
  completion: zsh: fix for directories with spaces
  completion: remove zsh hack
  completion: zsh: improve main function selection
  completion: prompt: fix color for Zsh
  completion: bash: cleanup cygwin check
  completion: zsh: update installation instructions
  completion: bash: remove old compat wrappers
  completion: bash: remove zsh wrapper
  completion: zsh: trivial cleanups
  test: completion: tests for __gitcomp regression
  test: completion: use global config
  completion: add default options
  completion: add default merge strategies

 contrib/completion/git-completion.bash | 202 +
 contrib/completion/git-completion.zsh  |  53 +++
 contrib/completion/git-prompt.sh   |  10 +-
 t/t9902-completion.sh  |  37 +++--
 4 files changed, 161 insertions(+), 141 deletions(-)

-- 
2.22.0



[PATCH 10/14] completion: zsh: trivial cleanups

2019-06-21 Thread Felipe Contreras
We don't need to override IFS, zsh has a native way of splitting by new
lines: the expansion flag (f).

Also, we don't need to split files by ':' or '='; that's only for words.

Signed-off-by: Felipe Contreras 
---
 contrib/completion/git-completion.zsh | 18 ++
 1 file changed, 6 insertions(+), 12 deletions(-)

diff --git a/contrib/completion/git-completion.zsh 
b/contrib/completion/git-completion.zsh
index 7f614d5854..317f5bd80a 100644
--- a/contrib/completion/git-completion.zsh
+++ b/contrib/completion/git-completion.zsh
@@ -68,44 +68,38 @@ __gitcomp_direct ()
 {
emulate -L zsh
 
-   local IFS=$'\n'
compset -P '*[=:]'
-   compadd -Q -- ${${=1}% } && _ret=0
+   compadd -Q -- ${${(f)1}% } && _ret=0
 }
 
 __gitcomp_nl ()
 {
emulate -L zsh
 
-   local IFS=$'\n'
compset -P '*[=:]'
-   compadd -Q -S "${4- }" -p "${2-}" -- ${=1} && _ret=0
+   compadd -Q -S "${4- }" -p "${2-}" -- ${(f)1} && _ret=0
 }
 
 __gitcomp_nl_append ()
 {
emulate -L zsh
 
-   local IFS=$'\n'
-   compadd -Q -S "${4- }" -p "${2-}" -- ${=1} && _ret=0
+   compset -P '*[=:]'
+   compadd -Q -S "${4- }" -p "${2-}" -- ${(f)1} && _ret=0
 }
 
 __gitcomp_file_direct ()
 {
emulate -L zsh
 
-   local IFS=$'\n'
-   compset -P '*[=:]'
-   compadd -f -- ${=1} && _ret=0
+   compadd -f -- ${(f)1} && _ret=0
 }
 
 __gitcomp_file ()
 {
emulate -L zsh
 
-   local IFS=$'\n'
-   compset -P '*[=:]'
-   compadd -p "${2-}" -f -- ${=1} && _ret=0
+   compadd -f -p "${2-}" -- ${(f)1} && _ret=0
 }
 
 __git_zsh_bash_func ()
-- 
2.22.0



[PATCH 08/14] completion: bash: remove old compat wrappers

2019-06-21 Thread Felipe Contreras
It's been seven years, probably more than enough time to move on.

Signed-off-by: Felipe Contreras 
---
 contrib/completion/git-completion.bash | 12 
 1 file changed, 12 deletions(-)

diff --git a/contrib/completion/git-completion.bash 
b/contrib/completion/git-completion.bash
index dba822d0e7..1f9b833913 100644
--- a/contrib/completion/git-completion.bash
+++ b/contrib/completion/git-completion.bash
@@ -3073,18 +3073,6 @@ __git_complete ()
|| complete -o default -o nospace -F $wrapper $1
 }
 
-# wrapper for backwards compatibility
-_git ()
-{
-   __git_wrap__git_main
-}
-
-# wrapper for backwards compatibility
-_gitk ()
-{
-   __git_wrap__gitk_main
-}
-
 __git_complete git __git_main
 __git_complete gitk __gitk_main
 
-- 
2.22.0



[PATCH 02/14] completion: zsh: fix for directories with spaces

2019-06-21 Thread Felipe Contreras
Signed-off-by: Felipe Contreras 
---
 contrib/completion/git-completion.zsh | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/contrib/completion/git-completion.zsh 
b/contrib/completion/git-completion.zsh
index 0d66c27366..034cfa9e8f 100644
--- a/contrib/completion/git-completion.zsh
+++ b/contrib/completion/git-completion.zsh
@@ -30,7 +30,7 @@ if [ -z "$script" ]; then
local -a locations
local e
locations=(
-   $(dirname ${funcsourcetrace[1]%:*})/git-completion.bash
+   "$(dirname ${funcsourcetrace[1]%:*})"/git-completion.bash
'/etc/bash_completion.d/git' # fedora, old debian
'/usr/share/bash-completion/completions/git' # arch, ubuntu, 
new debian
'/usr/share/bash-completion/git' # gentoo
-- 
2.22.0



[PATCH 04/14] completion: zsh: improve main function selection

2019-06-21 Thread Felipe Contreras
Sometimes we want to use the function directly (e.g. _git_checkout), for
example when zsh has the option 'complete_aliases', this way, we can do
something like:

  compdef _git gco=git_checkout

Signed-off-by: Felipe Contreras 
---
 contrib/completion/git-completion.zsh | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/contrib/completion/git-completion.zsh 
b/contrib/completion/git-completion.zsh
index aade33ec9f..2801f2f7c8 100644
--- a/contrib/completion/git-completion.zsh
+++ b/contrib/completion/git-completion.zsh
@@ -226,8 +226,10 @@ _git ()
 
if (( $+functions[__${service}_zsh_main] )); then
__${service}_zsh_main
-   else
+   elif (( $+functions[__${service}_main] )); then
emulate ksh -c __${service}_main
+   elif (( $+functions[_${service}] )); then
+   emulate ksh -c _${service}
fi
 
let _ret && _default && _ret=0
-- 
2.22.0



[PATCH 11/14] test: completion: tests for __gitcomp regression

2019-06-21 Thread Felipe Contreras
There's a regression in the completion since the introduction of
__gitcomp.

Go to any directory that doesn't contain a git repository, like /tmp.
Then type the following:

  git checkout --

You will see nothing. That's because
`git checkout --git-completion-helper` fails when you run it outside a
git repository.

You might change to a directory that has a git repository, but it's too
late, because the empty options have been cached.

It's unclear how many commands are affected, but this patch attempts to
at least detect some already in the testing framework.

Signed-off-by: Felipe Contreras 
---
 t/t9902-completion.sh | 37 -
 1 file changed, 28 insertions(+), 9 deletions(-)

diff --git a/t/t9902-completion.sh b/t/t9902-completion.sh
index 43cf313a1c..7bef41eaf5 100755
--- a/t/t9902-completion.sh
+++ b/t/t9902-completion.sh
@@ -122,6 +122,15 @@ test_gitcomp_nl ()
test_cmp expected out
 }
 
+offgit ()
+{
+   GIT_CEILING_DIRECTORIES="$ROOT" &&
+   export GIT_CEILING_DIRECTORIES &&
+   test_when_finished "ROOT='$ROOT'; cd '$TRASH_DIRECTORY'; unset 
GIT_CEILING_DIRECTORIES" &&
+   ROOT="$ROOT"/non-repo &&
+   cd "$ROOT"
+}
+
 invalid_variable_name='${foo.bar}'
 
 actual="$TRASH_DIRECTORY/actual"
@@ -358,10 +367,8 @@ test_expect_success SYMLINKS '__git_find_repo_path - 
resulting path avoids symli
 '
 
 test_expect_success '__git_find_repo_path - not a git repository' '
+   offgit &&
(
-   cd non-repo &&
-   GIT_CEILING_DIRECTORIES="$ROOT" &&
-   export GIT_CEILING_DIRECTORIES &&
test_must_fail __git_find_repo_path &&
printf "$__git_repo_path" >"$actual"
) &&
@@ -1388,6 +1395,7 @@ test_expect_success '__git_pretty_aliases' '
 '
 
 test_expect_success 'basic' '
+   offgit &&
run_completion "git " &&
# built-in
grep -q "^add \$" out &&
@@ -1401,6 +1409,7 @@ test_expect_success 'basic' '
 '
 
 test_expect_success 'double dash "git" itself' '
+   offgit &&
test_completion "git --" <<-\EOF
--paginate Z
--no-pager Z
@@ -1419,7 +1428,8 @@ test_expect_success 'double dash "git" itself' '
EOF
 '
 
-test_expect_success 'double dash "git checkout"' '
+test_expect_failure 'double dash "git checkout"' '
+   offgit &&
test_completion "git checkout --" <<-\EOF
--quiet Z
--detach Z
@@ -1442,6 +1452,7 @@ test_expect_success 'double dash "git checkout"' '
 '
 
 test_expect_success 'general options' '
+   offgit &&
test_completion "git --ver" "--version " &&
test_completion "git --hel" "--help " &&
test_completion "git --exe" <<-\EOF &&
@@ -1460,6 +1471,7 @@ test_expect_success 'general options' '
 '
 
 test_expect_success 'general options plus command' '
+   offgit &&
test_completion "git --version check" "checkout " &&
test_completion "git --paginate check" "checkout " &&
test_completion "git --git-dir=foo check" "checkout " &&
@@ -1480,11 +1492,13 @@ test_expect_success 'general options plus command' '
 '
 
 test_expect_success 'git --help completion' '
+   offgit &&
test_completion "git --help ad" "add " &&
test_completion "git --help core" "core-tutorial "
 '
 
-test_expect_success 'completion.commands removes multiple commands' '
+test_expect_failure 'completion.commands removes multiple commands' '
+   offgit &&
test_config completion.commands "-cherry -mergetool" &&
git --list-cmds=list-mainporcelain,list-complete,config >out &&
! grep -E "^(cherry|mergetool)$" out
@@ -1547,9 +1561,10 @@ test_expect_success 'complete tree filename with 
metacharacters' '
EOF
 '
 
-test_expect_success PERL 'send-email' '
-   test_completion "git send-email --cov" "--cover-letter " &&
-   test_completion "git send-email ma" "master "
+test_expect_failure PERL 'send-email' '
+   test_completion "git send-email ma" "master " &&
+   offgit &&
+   test_completion "git send-email --cov" "--cover-letter "
 '
 
 test_expect_success 'complete files' '
@@ -1649,6 +1664,7 @@ test_expect_success 'completion used  completion for 
alias: !f() { : git 

[PATCH 03/14] completion: remove zsh hack

2019-06-21 Thread Felipe Contreras
We don't want to override the 'complete()' function in zsh, which can be
used by bashcomp.

Reported-by: Mark Lodato 
Signed-off-by: Felipe Contreras 
---
 contrib/completion/git-completion.bash | 1 +
 contrib/completion/git-completion.zsh  | 6 --
 2 files changed, 1 insertion(+), 6 deletions(-)

diff --git a/contrib/completion/git-completion.bash 
b/contrib/completion/git-completion.bash
index a65d5956c1..676b19a983 100644
--- a/contrib/completion/git-completion.bash
+++ b/contrib/completion/git-completion.bash
@@ -3066,6 +3066,7 @@ __git_func_wrap ()
 # This is NOT a public function; use at your own risk.
 __git_complete ()
 {
+   test -n "$ZSH_VERSION" && return
local wrapper="__git_wrap${2}"
eval "$wrapper () { __git_func_wrap $2 ; }"
complete -o bashdefault -o default -o nospace -F $wrapper $1 
2>/dev/null \
diff --git a/contrib/completion/git-completion.zsh 
b/contrib/completion/git-completion.zsh
index 034cfa9e8f..aade33ec9f 100644
--- a/contrib/completion/git-completion.zsh
+++ b/contrib/completion/git-completion.zsh
@@ -16,12 +16,6 @@
 #
 #  fpath=(~/.zsh $fpath)
 
-complete ()
-{
-   # do nothing
-   return 0
-}
-
 zstyle -T ':completion:*:*:git:*' tag-order && \
zstyle ':completion:*:*:git:*' tag-order 'common-commands'
 
-- 
2.22.0



[PATCH 14/14] completion: add default merge strategies

2019-06-21 Thread Felipe Contreras
In case the command fails.

Signed-off-by: Felipe Contreras 
---
 contrib/completion/git-completion.bash | 4 +++-
 t/t9902-completion.sh  | 2 +-
 2 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/contrib/completion/git-completion.bash 
b/contrib/completion/git-completion.bash
index 922ba5f925..91b87eb558 100644
--- a/contrib/completion/git-completion.bash
+++ b/contrib/completion/git-completion.bash
@@ -936,6 +936,7 @@ __git_list_merge_strategies ()
}'
 }
 
+__git_merge_strategies_default='octopus ours recursive resolve subtree'
 __git_merge_strategies=
 # 'git merge -s help' (and thus detection of the merge strategy
 # list) fails, unfortunately, if run outside of any git working
@@ -945,7 +946,8 @@ __git_merge_strategies=
 __git_compute_merge_strategies ()
 {
test -n "$__git_merge_strategies" ||
-   __git_merge_strategies=$(__git_list_merge_strategies)
+   { __git_merge_strategies=$(__git_list_merge_strategies);
+   
__git_merge_strategies="${__git_merge_strategies:-__git_merge_strategies_default}";
 }
 }
 
 __git_merge_strategy_options="ours theirs subtree subtree= patience
diff --git a/t/t9902-completion.sh b/t/t9902-completion.sh
index 14598bfbec..f4453ce70d 100755
--- a/t/t9902-completion.sh
+++ b/t/t9902-completion.sh
@@ -1722,7 +1722,7 @@ test_expect_success 'sourcing the completion script 
clears cached commands' '
verbose test -z "$__git_all_commands"
 '
 
-test_expect_failure 'sourcing the completion script clears cached merge 
strategies' '
+test_expect_success 'sourcing the completion script clears cached merge 
strategies' '
offgit &&
GIT_TEST_GETTEXT_POISON= &&
__git_compute_merge_strategies &&
-- 
2.22.0



[PATCH 01/14] completion: zsh: fix __gitcomp_direct()

2019-06-21 Thread Felipe Contreras
Many callers append a space suffix, but zsh automatically appends a
space, making the completion add two spaces, for example:

  git log ma

Will complete 'master  '.

Let's remove that extra space.

Signed-off-by: Felipe Contreras 
---
 contrib/completion/git-completion.bash | 2 +-
 contrib/completion/git-completion.zsh  | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/contrib/completion/git-completion.bash 
b/contrib/completion/git-completion.bash
index 9f71bcde96..a65d5956c1 100644
--- a/contrib/completion/git-completion.bash
+++ b/contrib/completion/git-completion.bash
@@ -3009,7 +3009,7 @@ if [[ -n ${ZSH_VERSION-} ]] &&
 
local IFS=$'\n'
compset -P '*[=:]'
-   compadd -Q -- ${=1} && _ret=0
+   compadd -Q -- ${${=1}% } && _ret=0
}
 
__gitcomp_nl ()
diff --git a/contrib/completion/git-completion.zsh 
b/contrib/completion/git-completion.zsh
index 886bf95d1f..0d66c27366 100644
--- a/contrib/completion/git-completion.zsh
+++ b/contrib/completion/git-completion.zsh
@@ -73,7 +73,7 @@ __gitcomp_direct ()
 
local IFS=$'\n'
compset -P '*[=:]'
-   compadd -Q -- ${=1} && _ret=0
+   compadd -Q -- ${${=1}% } && _ret=0
 }
 
 __gitcomp_nl ()
-- 
2.22.0



Re: [PATCH 13/14] completion: add default options

2019-06-21 Thread Felipe Contreras
On Fri, Jun 21, 2019 at 10:02 PM Duy Nguyen  wrote:
>
> On Sat, Jun 22, 2019 at 5:31 AM Felipe Contreras
>  wrote:
> >
> > Versions of Git older than v2.17 don't know about
> > --git-completion-helper, so provide some defaults for them.
> >
> > Also, some commands fail if there's no Git repository available.
> >
> > Signed-off-by: Felipe Contreras 
> > ---
> >  contrib/completion/git-completion.bash | 97 +-
> >  t/t9902-completion.sh  |  4 +-
> >  2 files changed, 98 insertions(+), 3 deletions(-)
> >
> > diff --git a/contrib/completion/git-completion.bash 
> > b/contrib/completion/git-completion.bash
> > index d3ee6c7dc2..922ba5f925 100644
> > --- a/contrib/completion/git-completion.bash
> > +++ b/contrib/completion/git-completion.bash
> > @@ -377,6 +377,100 @@ else
> > unset $(compgen -v __gitcomp_builtin_)
> >  fi
> >
> > +__gitcomp_builtin_add_default=" --dry-run --verbose --interactive --patch 
> > --edit --force --update --renormalize --intent-to-add --all --ignore-
> removal --refresh --ignore-errors --ignore-missing --chmod=
> --no-dry-run -- --no-verbose --no-interactive --no-patch --no-edit
> --no-force --no-update --no-renormalize --no-intent-to-add --no-all
> --no-ignore-removal --no-refresh --no-ignore-errors
> --no-ignore-missing --no-chmod"
>
> And who's going to keep these uptodate?

The same people that kept them up-to-date before git-completion-helper.

> If you do this, might as well delete --git-completion-helper

They serve two different purposes. Say you install the completion of
Git v2.22, but a while later you have Git v2.25; you will get the
updated commands thanks to git-completion-helper, and all the
__gitcomp_builtin_*_default will be ignored.

Granted; that's not the typical situation, as many people get the Git
completion through their distribution in tandem with their Git
version. But remember that these completion scripts are part of
contrib; they are not part of official Git (`make install` doesn't
install them).

When a) most people have a version of git that has
git-completion-helper, and b) most of the issues running commands
outside of a Git repo are resolved, they could be removed. But right
now they do serve a purpose.

> A more acceptable option might be regenerate git-completion.bash and
> run --git-completion-helper to generate these, or make
> git-completion.bash source a generated file. But that might need some
> more build infrastructure, and people who just one to copy the file
> might not like it.

Indeed, I wrote a script to generate these, but I manually copied
them. I could write a script that automatically generates this file if
it's agreed that this is indeed the way we want to go.

But even if these were not up-to-date--as historically has been the
case for most options--and a) you are running a version of Git that
doesn't have git-completion-helper, or b) you run a command that
requires a Git repo; it's better to get outdated options than to get
*nothing*, which is what we get now.

Cheers.

-- 
Felipe Contreras


Re: [PATCH 01/14] completion: zsh: fix __gitcomp_direct()

2019-06-22 Thread Felipe Contreras
On Fri, Jun 21, 2019 at 5:31 PM Felipe Contreras
 wrote:
>
> Many callers append a space suffix, but zsh automatically appends a
> space, making the completion add two spaces, for example:

> --- a/contrib/completion/git-completion.zsh
> +++ b/contrib/completion/git-completion.zsh
> @@ -73,7 +73,7 @@ __gitcomp_direct ()
>
> local IFS=$'\n'
> compset -P '*[=:]'
> -   compadd -Q -- ${=1} && _ret=0
> +   compadd -Q -- ${${=1}% } && _ret=0

This is better actually:

compadd -Q -S '' -- ${=1} && _ret=0

-- 
Felipe Contreras


Re: [PATCH 14/14] completion: add default merge strategies

2019-06-24 Thread Felipe Contreras
On Mon, Jun 24, 2019 at 12:24 PM Junio C Hamano  wrote:
>
> Felipe Contreras  writes:
>
> > In case the command fails.
>
> It is unclear what you wanted to say with this.  What command?
> After "git merge" fails?

Yes. The command that __git_list_merge_strategies() uses.

 % cd /tmp
 % git merge -s help
fatal: not a git repository (or any parent up to mount point /)
Stopping at filesystem boundary (GIT_DISCOVERY_ACROSS_FILESYSTEM not set).

-- 
Felipe Contreras


Re: [PATCH 13/14] completion: add default options

2019-06-24 Thread Felipe Contreras
On Mon, Jun 24, 2019 at 12:22 PM Junio C Hamano  wrote:
>
> Duy Nguyen  writes:
>
> > On Sat, Jun 22, 2019 at 5:31 AM Felipe Contreras
> >  wrote:
> >>
> >> Versions of Git older than v2.17 don't know about
> >> --git-completion-helper, so provide some defaults for them.
> > ...
> >> +__gitcomp_builtin_add_default=" --dry-run --verbose --interactive --patch 
> >> --edit --force --update --renormalize --intent-to-add --all --ignore-
> > removal --refresh --ignore-errors --ignore-missing --chmod=
> > --no-dry-run -- --no-verbose --no-interactive --no-patch --no-edit
> > --no-force --no-update --no-renormalize --no-intent-to-add --no-all
> > --no-ignore-removal --no-refresh --no-ignore-errors
> > --no-ignore-missing --no-chmod"
> >
> > And who's going to keep these uptodate? If you do this, might as well
> > delete --git-completion-helper
> >
> > A more acceptable option might be regenerate git-completion.bash and
> > run --git-completion-helper to generate these, or make
> > git-completion.bash source a generated file.
>
> Nicely analysed and summarized.  What kind of target audience are we
> talking about?

The people that install their completion independently of their
distribution. A quick search in Stack Overflow shows hundreds of
questions, many related to Homebrew and Cygwin.

> What's the payoff vs cost comparison trying to
> catering to those who install more recent completion script that
> requires the --git-completion-helper option without using antient
> Git?

You use the adjective "ancient", but is it really? The current Ubuntu
LTS release uses
2.17.1, the previous one (supported until 2021) uses 2.7.4, the
current Debian stable uses 2.11.0, and the previous RHEL uses 2.3.5.

Travis CI runs 2.15.1 by default.

If you are going to call these "ancient" what would you call the
current version in Debian oldstable? 2.1.4.

Not everyone is a privileged as us.

> If the cutoff boundary is 2.17, that is more than year ago, and the
> boundary gets further and further in the past as time goes by. Also,
> depending on how old the version of Git the target user runs, these
> hardcoded and manually listed options may not yet even exist in
> their binary.

Indeed, the need for these defaults will diminish over time, but
*right now* people are running versions of Git older than 2.17, for
sure.

And yes, it's possible that the completion will return an option that
doesn't exist yet in the user's version of Git, but historically that
has always been the case regarding Git completions (at least until
git-completion-helper).

So what would you rather have? a) return potentially non-existent
completions, or b) don't complete anything?

Another idea I had is to have a separate 'git completion-helper'
command that could act as a proxy for `git cmd
--git-completion-helper` and `git --list-cmds`. The completion would
throw a warning if such command is missing, then, the person that
installed the completion would have to find a suitable `git
completion-helper` command. We could provide an "example" script that
contains all these defaults. People could modify this to generate the
correct options for different Git versions. Realistically though, most
people will just use the defaults for the latest version, but at least
the responsibility is not on your side.

Cheers.

-- 
Felipe Contreras


RE: Our official home page and logo for the Git project

2014-04-09 Thread Felipe Contreras
Junio C Hamano wrote:
>  - To officially adopt the logo that appears on the "project
>home page" as our "project logo".

I have made my objections to that logo before, but here it goes again: bright
red is a horrible color for a logo, as it only looks good in limited
situations. I propose you use the logo I chose for git-fc[1] which has a better
color, and instead of showing commits going down, they go up.

Here[2] you can see how horrible contrast this brigth red makes.

[1] http://felipec.files.wordpress.com/2013/10/git-fc2.png
[2] http://felipec.org/contrast.png

-- 
Felipe Contreras
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


RE: [ANNOUNCE] WinGit - native x86/x64 Git for Windows

2014-04-09 Thread Felipe Contreras
marat@ wrote:
> I'm proud to announce WinGit: an attempt to bring Git powers to 64-bit
> Windows.
> 
> WinGit is currently used only by my coworkers and isn't considered
> production-ready-rock-solid. Use at your own risk.

Thank you for doing this, it's very much needed. It would be great if there was
a place to list all the tools that need to be converted to C, so that neither
Perl, nor a shell are needed for most of Git's operations, don't you think?

Cheers.

-- 
Felipe Contreras
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: fast-import deltas

2014-04-09 Thread Felipe Contreras
Mike Hommey wrote:
> On Wed, Apr 02, 2014 at 01:29:13AM +0200, Max Horn wrote:
> > I wonder if it is really worth the effort to start yet another project on
> > this... Moreover, I don't see a fundamental reason why one could not modify
> > git-remote-hg to work this way.
> 
> The way git-remote-hg works is fundamentally different to how one can
> directly get and push stuff to a remote mercurial server.

That is why you would modify it; so it does what you want, and instead of using
remote-helper's import/export, it would use fetch/push.

Either way, I say you should hack Git and do as many changes as you want, and
once you have some numbers, it would be clearer what approach should be the
ideal one, how much is the benefit, and then we could discuss if it's worth the
modifications in Git needed.

-- 
Felipe Contreras
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 0/5] Fixes

2014-04-09 Thread Felipe Contreras
Felipe Contreras (4):
  remote-helpers: allow all tests running from any dir
  remote-hg: always normalize paths
  remote-bzr: add support for older versions
  completion: fix completion of certain aliases

dequis (1):
  remote-bzr: include authors field in pushed commits

 contrib/completion/git-completion.bash   |  1 +
 contrib/completion/git-completion.zsh|  1 +
 contrib/remote-helpers/git-remote-bzr|  6 --
 contrib/remote-helpers/git-remote-hg |  1 +
 contrib/remote-helpers/test-bzr.sh   | 24 
 contrib/remote-helpers/test-hg-bidi.sh   |  3 ++-
 contrib/remote-helpers/test-hg-hg-git.sh |  3 ++-
 7 files changed, 35 insertions(+), 4 deletions(-)

-- 
1.9.1+fc1

--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 2/5] remote-hg: always normalize paths

2014-04-09 Thread Felipe Contreras
Apparently Mercurial can have paths such as 'foo//bar', so normalize all
paths.

Signed-off-by: Felipe Contreras 
---
 contrib/remote-helpers/git-remote-hg | 1 +
 1 file changed, 1 insertion(+)

diff --git a/contrib/remote-helpers/git-remote-hg 
b/contrib/remote-helpers/git-remote-hg
index eb89ef6..84e3872 100755
--- a/contrib/remote-helpers/git-remote-hg
+++ b/contrib/remote-helpers/git-remote-hg
@@ -260,6 +260,7 @@ class Parser:
 return (user, int(date), -tz)
 
 def fix_file_path(path):
+path = os.path.normpath(path)
 if not os.path.isabs(path):
 return path
 return os.path.relpath(path, '/')
-- 
1.9.1+fc1

--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 1/5] remote-helpers: allow all tests running from any dir

2014-04-09 Thread Felipe Contreras
Commit d3243d7 (test-bzr.sh, test-hg.sh: allow running from any dir)
allowed the tests to run from any directory, however, it didn't update
all the tests.

Signed-off-by: Felipe Contreras 
---
 contrib/remote-helpers/test-hg-bidi.sh   | 3 ++-
 contrib/remote-helpers/test-hg-hg-git.sh | 3 ++-
 2 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/contrib/remote-helpers/test-hg-bidi.sh 
b/contrib/remote-helpers/test-hg-bidi.sh
index e24c51d..d86e147 100755
--- a/contrib/remote-helpers/test-hg-bidi.sh
+++ b/contrib/remote-helpers/test-hg-bidi.sh
@@ -8,7 +8,8 @@
 
 test_description='Test bidirectionality of remote-hg'
 
-. ./test-lib.sh
+test -n "$TEST_DIRECTORY" || TEST_DIRECTORY=${0%/*}/../../t
+. "$TEST_DIRECTORY"/test-lib.sh
 
 if ! test_have_prereq PYTHON
 then
diff --git a/contrib/remote-helpers/test-hg-hg-git.sh 
b/contrib/remote-helpers/test-hg-hg-git.sh
index 6dcd95d..b23909a 100755
--- a/contrib/remote-helpers/test-hg-hg-git.sh
+++ b/contrib/remote-helpers/test-hg-hg-git.sh
@@ -8,7 +8,8 @@
 
 test_description='Test remote-hg output compared to hg-git'
 
-. ./test-lib.sh
+test -n "$TEST_DIRECTORY" || TEST_DIRECTORY=${0%/*}/../../t
+. "$TEST_DIRECTORY"/test-lib.sh
 
 if ! test_have_prereq PYTHON
 then
-- 
1.9.1+fc1

--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 3/5] remote-bzr: add support for older versions

2014-04-09 Thread Felipe Contreras
Signed-off-by: Felipe Contreras 
---
 contrib/remote-helpers/git-remote-bzr | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/contrib/remote-helpers/git-remote-bzr 
b/contrib/remote-helpers/git-remote-bzr
index 332aba7..7f354c8 100755
--- a/contrib/remote-helpers/git-remote-bzr
+++ b/contrib/remote-helpers/git-remote-bzr
@@ -759,7 +759,7 @@ def clone(path, remote_branch):
 def get_remote_branch(name):
 remote_branch = bzrlib.branch.Branch.open(branches[name],
   possible_transports=transports)
-if isinstance(remote_branch.user_transport, 
bzrlib.transport.local.LocalTransport):
+if isinstance(remote_branch.bzrdir.root_transport, 
bzrlib.transport.local.LocalTransport):
 return remote_branch
 
 branch_path = os.path.join(dirname, 'clone', name)
@@ -842,7 +842,7 @@ def get_repo(url, alias):
 if not wanted:
 try:
 repo = origin.open_repository()
-if not repo.user_transport.listable():
+if not repo.bzrdir.root_transport.listable():
 # this repository is not usable for us
 raise bzrlib.errors.NoRepositoryPresent(repo.bzrdir)
 except bzrlib.errors.NoRepositoryPresent:
-- 
1.9.1+fc1

--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 5/5] completion: fix completion of certain aliases

2014-04-09 Thread Felipe Contreras
Some commands need the first word to determine the actual action that is
being executed, however, the command is wrong when we use an alias, for
example 'alias.p=push', if we try to complete 'git p origin ', the
result would be wrong because __git_complete_remote_or_refspec() doesn't
know where it come from.

So let's override words[1], so the alias 'p' is override by the actual
command, 'push'.

Reported-by: Aymeric Beaumet 
Signed-off-by: Felipe Contreras 
---
 contrib/completion/git-completion.bash | 1 +
 contrib/completion/git-completion.zsh  | 1 +
 2 files changed, 2 insertions(+)

diff --git a/contrib/completion/git-completion.bash 
b/contrib/completion/git-completion.bash
index 9525343..893ae5d 100644
--- a/contrib/completion/git-completion.bash
+++ b/contrib/completion/git-completion.bash
@@ -2547,6 +2547,7 @@ __git_main ()
 
local expansion=$(__git_aliased_command "$command")
if [ -n "$expansion" ]; then
+   words[1]=$expansion
completion_func="_git_${expansion//-/_}"
declare -f $completion_func >/dev/null && $completion_func
fi
diff --git a/contrib/completion/git-completion.zsh 
b/contrib/completion/git-completion.zsh
index 6b77968..9f6f0fa 100644
--- a/contrib/completion/git-completion.zsh
+++ b/contrib/completion/git-completion.zsh
@@ -104,6 +104,7 @@ __git_zsh_bash_func ()
 
local expansion=$(__git_aliased_command "$command")
if [ -n "$expansion" ]; then
+   words[1]=$expansion
completion_func="_git_${expansion//-/_}"
declare -f $completion_func >/dev/null && $completion_func
fi
-- 
1.9.1+fc1

--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 4/5] remote-bzr: include authors field in pushed commits

2014-04-09 Thread Felipe Contreras
From: dequis 

Tests-by: Felipe Contreras 
Signed-off-by: Felipe Contreras 
---
 contrib/remote-helpers/git-remote-bzr |  2 ++
 contrib/remote-helpers/test-bzr.sh| 24 
 2 files changed, 26 insertions(+)

diff --git a/contrib/remote-helpers/git-remote-bzr 
b/contrib/remote-helpers/git-remote-bzr
index 7f354c8..6ca1e97 100755
--- a/contrib/remote-helpers/git-remote-bzr
+++ b/contrib/remote-helpers/git-remote-bzr
@@ -618,10 +618,12 @@ def parse_commit(parser):
 files[path] = f
 
 committer, date, tz = committer
+author, _, _ = author
 parents = [mark_to_rev(p) for p in parents]
 revid = bzrlib.generate_ids.gen_revision_id(committer, date)
 props = {}
 props['branch-nick'] = branch.nick
+props['authors'] = author
 
 mtree = CustomTree(branch, revid, parents, files)
 changes = mtree.iter_changes()
diff --git a/contrib/remote-helpers/test-bzr.sh 
b/contrib/remote-helpers/test-bzr.sh
index 1e53ff9..431de3b 100755
--- a/contrib/remote-helpers/test-bzr.sh
+++ b/contrib/remote-helpers/test-bzr.sh
@@ -391,4 +391,28 @@ test_expect_success 'export utf-8 authors' '
test_cmp expected actual
 '
 
+test_expect_success 'push different author' '
+   test_when_finished "rm -rf bzrrepo gitrepo" &&
+
+   bzr init bzrrepo &&
+
+   (
+   git init gitrepo &&
+   cd gitrepo &&
+   echo john >> content &&
+   git add content &&
+   git commit -m john --author "John Doe " &&
+   git remote add bzr "bzr::../bzrrepo" &&
+   git push bzr master
+   ) &&
+
+   (
+   cd bzrrepo &&
+   bzr log | grep "^author: " > ../actual
+   ) &&
+
+   echo "author: John Doe " > expected &&
+   test_cmp expected actual
+'
+
 test_done
-- 
1.9.1+fc1

--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 5/5] completion: fix completion of certain aliases

2014-04-09 Thread Felipe Contreras
Junio C Hamano wrote:
> Felipe Contreras  writes:
> 
> > Some commands need the first word to determine the actual action that is
> > being executed, however, the command is wrong when we use an alias, for
> > example 'alias.p=push', if we try to complete 'git p origin ', the
> > result would be wrong because __git_complete_remote_or_refspec() doesn't
> > know where it come from.
> >
> > So let's override words[1], so the alias 'p' is override by the actual
> > command, 'push'.
> >
> > Reported-by: Aymeric Beaumet 
> > Signed-off-by: Felipe Contreras 
> > ---
> 
> Does "some commands" above refer to anything that uses
> __git_complete_remote_or_refspec, or is the set of commands larger than that?

For this particular issue, yes, the former.

> But perhaps we muck with the contents of words[] in a similar way in many
> different places in the existing completion code often enough that such an
> attempt not to touch the words[] array does not buy us much safety anyway.  I
> didn't check (and that is why I am asking with "I am wondering...").

The 'words' array is already messed up and not used correctly, so I wouldn't
worry too much about this patch messing it more (I don't see how that can be).

For example:
  % git --git-dir=$PWD/.git fetch or

-- 
Felipe Contreras
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


RE: [PATCH] Add support for commit attributes

2014-04-10 Thread Felipe Contreras
Diego Lago wrote:
> Commit attributes are custom commit extra headers the user can
> add to the commit object.
> 
> The motivation for this patch is that in my company we have a custom
> continuous integration software that uses a custom formatted commit
> message (currently in YALM format) to show several information into
> our CI server front-end.

These attributes can be used for remote-helpers as well; to store extra
information that cannot be stored otherwise in Git's data structures.

-- 
Felipe Contreras
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 0/9] Introduce publish tracking branch

2014-04-10 Thread Felipe Contreras
As it has been discussed before, our support for triangular workflows is
lacking, and the following patch series aims to improve that situation.

We have the concept of upstream branch (e.g. 'origin/master') which is to where
our topic branches eventually should be merged to, so it makes sense that
'git rebase' uses that as the destination, but most people would not push to
such upstream branch, they would push to a publish branch
(e.g. 'github/feature-a'). We could set our upstream to the place we push, and
'git push' would be able to use that as default, and 'git branch --vv' would
show how ahead/behind we are in comparisson to that branch, but then
'git rebase' (or 'git merge') would be using the wrong branch.

This patch series adds:

 1) git push --set-publish
 2) git branch --set-publish
 3) git branch -vv # uses and shows the publish branch when configured
 4) @{publish} and @{p} marks
 5) branch.$name.{push,pushremote} configurations

After this, it becomes much easier to track branches in a triangular workflow.

The publish branch is used instead of the upstream branch for tracking
information in 'git branch --vv' and 'git status' if present, otherwise there
are no changes (upstream is used).

  master  e230c56 [origin/master, gh/master] Git 1.8.4
* fc/publish  0a105fd [master, gh/fc/publish: ahead 1] branch: display 
publish branch
  fc/branch/fast  177dcad [master, gh/fc/branch/fast] branch: reorganize 
verbose options
  fc/trivial  f289b9a [master: ahead 7] branch: trivial style fix
  fc/leaksd101af4 [master: ahead 2] read-cache: plug a possible leak
  stable  e230c56 Git 1.8.4

Changes since v1:

 * Added @{publish} and @{p} marks

Felipe Contreras (9):
  push: trivial reorganization
  Add concept of 'publish' branch
  branch: allow configuring the publish branch
  t: branch add publish branch tests
  push: add --set-publish option
  branch: display publish branch
  sha1_name: cleanup interpret_branch_name()
  sha1_name: simplify track finding
  sha1_name: add support for @{publish} marks

 Documentation/git-branch.txt | 11 +++
 Documentation/git-push.txt   |  9 +-
 Documentation/revisions.txt  |  4 +++
 branch.c | 43 +
 branch.h |  2 ++
 builtin/branch.c | 74 ++
 builtin/push.c   | 52 +++---
 remote.c | 34 
 remote.h |  4 +++
 sha1_name.c  | 62 ++--
 t/t1508-at-combinations.sh   |  5 +++
 t/t3200-branch.sh| 76 
 t/t5529-push-publish.sh  | 70 
 t/t6040-tracking-info.sh |  5 +--
 transport.c  | 28 ++--
 transport.h  |  1 +
 16 files changed, 415 insertions(+), 65 deletions(-)
 create mode 100755 t/t5529-push-publish.sh

-- 
1.9.1+fc1

--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 1/9] push: trivial reorganization

2014-04-10 Thread Felipe Contreras
Signed-off-by: Felipe Contreras 
---
 builtin/push.c | 35 +++
 1 file changed, 19 insertions(+), 16 deletions(-)

diff --git a/builtin/push.c b/builtin/push.c
index 0e50ddb..d10aefc 100644
--- a/builtin/push.c
+++ b/builtin/push.c
@@ -155,20 +155,11 @@ static NORETURN int die_push_simple(struct branch 
*branch, struct remote *remote
remote->name, branch->name, advice_maybe);
 }
 
-static const char message_detached_head_die[] =
-   N_("You are not currently on a branch.\n"
-  "To push the history leading to the current (detached HEAD)\n"
-  "state now, use\n"
-  "\n"
-  "git push %s HEAD:\n");
-
 static void setup_push_upstream(struct remote *remote, struct branch *branch,
int triangular)
 {
struct strbuf refspec = STRBUF_INIT;
 
-   if (!branch)
-   die(_(message_detached_head_die), remote->name);
if (!branch->merge_nr || !branch->merge || !branch->remote_name)
die(_("The current branch %s has no upstream branch.\n"
"To push the current branch and set the remote as upstream, 
use\n"
@@ -198,8 +189,6 @@ static void setup_push_upstream(struct remote *remote, 
struct branch *branch,
 
 static void setup_push_current(struct remote *remote, struct branch *branch)
 {
-   if (!branch)
-   die(_(message_detached_head_die), remote->name);
add_refspec(branch->name);
 }
 
@@ -240,9 +229,23 @@ static int is_workflow_triangular(struct remote *remote)
return (fetch_remote && fetch_remote != remote);
 }
 
-static void setup_default_push_refspecs(struct remote *remote)
+static const char message_detached_head_die[] =
+   N_("You are not currently on a branch.\n"
+  "To push the history leading to the current (detached HEAD)\n"
+  "state now, use\n"
+  "\n"
+  "git push %s HEAD:\n");
+
+static struct branch *get_current_branch(struct remote *remote)
 {
struct branch *branch = branch_get(NULL);
+   if (!branch)
+   die(_(message_detached_head_die), remote->name);
+   return branch;
+}
+
+static void setup_default_push_refspecs(struct remote *remote)
+{
int triangular = is_workflow_triangular(remote);
 
switch (push_default) {
@@ -257,17 +260,17 @@ static void setup_default_push_refspecs(struct remote 
*remote)
 
case PUSH_DEFAULT_SIMPLE:
if (triangular)
-   setup_push_current(remote, branch);
+   setup_push_current(remote, get_current_branch(remote));
else
-   setup_push_upstream(remote, branch, triangular);
+   setup_push_upstream(remote, get_current_branch(remote), 
triangular);
break;
 
case PUSH_DEFAULT_UPSTREAM:
-   setup_push_upstream(remote, branch, triangular);
+   setup_push_upstream(remote, get_current_branch(remote), 
triangular);
break;
 
case PUSH_DEFAULT_CURRENT:
-   setup_push_current(remote, branch);
+   setup_push_current(remote, get_current_branch(remote));
break;
 
case PUSH_DEFAULT_NOTHING:
-- 
1.9.1+fc1

--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 3/9] branch: allow configuring the publish branch

2014-04-10 Thread Felipe Contreras
Signed-off-by: Felipe Contreras 
---
 Documentation/git-branch.txt | 11 +
 branch.c | 43 +
 branch.h |  2 ++
 builtin/branch.c | 57 
 4 files changed, 108 insertions(+), 5 deletions(-)

diff --git a/Documentation/git-branch.txt b/Documentation/git-branch.txt
index 311b336..914fd62 100644
--- a/Documentation/git-branch.txt
+++ b/Documentation/git-branch.txt
@@ -14,7 +14,9 @@ SYNOPSIS
[(--merged | --no-merged | --contains) []] [...]
 'git branch' [--set-upstream | --track | --no-track] [-l] [-f]  
[]
 'git branch' (--set-upstream-to= | -u ) []
+'git branch' (--set-publish-to= | -p ) []
 'git branch' --unset-upstream []
+'git branch' --unset-publish []
 'git branch' (-m | -M) [] 
 'git branch' (-d | -D) [-r] ...
 'git branch' --edit-description []
@@ -191,6 +193,15 @@ start-point is either a local or remote-tracking branch.
Remove the upstream information for . If no branch
is specified it defaults to the current branch.
 
+-p ::
+--set-publish-to=::
+   Set up 's publish tracking information. If no
+is specified, then it defaults to the current branch.
+
+--unset-publish::
+   Remove the publish information for . If no branch
+   is specified it defaults to the current branch.
+
 --edit-description::
Open an editor and edit the text to explain what the branch is
for, to be used by various other commands (e.g. `request-pull`).
diff --git a/branch.c b/branch.c
index 723a36b..6f4fe7f 100644
--- a/branch.c
+++ b/branch.c
@@ -144,6 +144,49 @@ static int setup_tracking(const char *new_ref, const char 
*orig_ref,
return 0;
 }
 
+void install_branch_publish(const char *name, const char *remote, const char 
*remote_ref)
+{
+   struct strbuf key = STRBUF_INIT;
+
+   if (!remote && !strcmp(name, remote_ref + 11) && !prefixcmp(remote_ref, 
"refs/heads")) {
+   warning(_("Not setting branch %s as its own publish branch."), 
name);
+   return;
+   }
+
+   strbuf_addf(&key, "branch.%s.pushremote", name);
+   git_config_set(key.buf, remote ? remote : ".");
+
+   strbuf_reset(&key);
+   strbuf_addf(&key, "branch.%s.push", name);
+   git_config_set(key.buf, remote_ref);
+
+   strbuf_release(&key);
+}
+
+int setup_publish(const char *name, const char *ref)
+{
+   struct tracking tracking;
+   const char *remote, *remote_ref;
+
+   memset(&tracking, 0, sizeof(tracking));
+   tracking.spec.dst = (char*)ref;
+   if (for_each_remote(find_tracked_branch, &tracking))
+   return 1;
+
+   if (tracking.matches > 1)
+   return error(_("Not tracking: ambiguous information for ref 
%s"),
+   ref);
+
+   remote = tracking.remote;
+   remote_ref = tracking.src ? tracking.src : ref;
+
+   install_branch_publish(name, remote, remote_ref);
+
+   free(tracking.src);
+
+   return 0;
+}
+
 struct branch_desc_cb {
const char *config_name;
const char *value;
diff --git a/branch.h b/branch.h
index 64173ab..c9b6aa9 100644
--- a/branch.h
+++ b/branch.h
@@ -51,5 +51,7 @@ extern void install_branch_config(int flag, const char 
*local, const char *origi
  * Read branch description
  */
 extern int read_branch_desc(struct strbuf *, const char *branch_name);
+extern int setup_publish(const char *name, const char *ref);
+extern void install_branch_publish(const char *name, const char *remote, const 
char *remote_ref);
 
 #endif
diff --git a/builtin/branch.c b/builtin/branch.c
index b4d7716..17773d7 100644
--- a/builtin/branch.c
+++ b/builtin/branch.c
@@ -793,8 +793,8 @@ int cmd_branch(int argc, const char **argv, const char 
*prefix)
int delete = 0, rename = 0, force_create = 0, list = 0;
int verbose = 0, abbrev = -1, detached = 0;
int reflog = 0, edit_description = 0;
-   int quiet = 0, unset_upstream = 0;
-   const char *new_upstream = NULL;
+   int quiet = 0, unset_upstream = 0, unset_publish = 0;
+   const char *new_upstream = NULL, *publish = NULL;
enum branch_track track;
int kinds = REF_LOCAL_BRANCH;
struct commit_list *with_commit = NULL;
@@ -809,7 +809,9 @@ int cmd_branch(int argc, const char **argv, const char 
*prefix)
OPT_SET_INT( 0, "set-upstream",  &track, N_("change upstream 
info"),
BRANCH_TRACK_OVERRIDE),
OPT_STRING('u', "set-upstream-to", &new_upstream, "upstream", 
"change the upstream info"),
+   OPT_STRING('p', "set-publish-to", &publish, "pub

[PATCH v2 2/9] Add concept of 'publish' branch

2014-04-10 Thread Felipe Contreras
The upstream branch is:

  branch.$name.remote
  branch.$name.merge

The publish branch is:

  branch.$name.pushremote
  branch.$name.push

Signed-off-by: Felipe Contreras 
---
 builtin/push.c | 19 +++
 remote.c   | 34 --
 remote.h   |  4 
 3 files changed, 47 insertions(+), 10 deletions(-)

diff --git a/builtin/push.c b/builtin/push.c
index d10aefc..a1fdc49 100644
--- a/builtin/push.c
+++ b/builtin/push.c
@@ -192,6 +192,20 @@ static void setup_push_current(struct remote *remote, 
struct branch *branch)
add_refspec(branch->name);
 }
 
+static void setup_push_simple(struct remote *remote, struct branch *branch,
+   int triangular)
+{
+   if (branch->push_name) {
+   struct strbuf refspec = STRBUF_INIT;
+   strbuf_addf(&refspec, "%s:%s", branch->name, branch->push_name);
+   add_refspec(refspec.buf);
+   } else if (triangular) {
+   setup_push_current(remote, branch);
+   } else {
+   setup_push_upstream(remote, branch, triangular);
+   }
+}
+
 static char warn_unspecified_push_default_msg[] =
 N_("push.default is unset; its implicit value is changing in\n"
"Git 2.0 from 'matching' to 'simple'. To squelch this message\n"
@@ -259,10 +273,7 @@ static void setup_default_push_refspecs(struct remote 
*remote)
break;
 
case PUSH_DEFAULT_SIMPLE:
-   if (triangular)
-   setup_push_current(remote, get_current_branch(remote));
-   else
-   setup_push_upstream(remote, get_current_branch(remote), 
triangular);
+   setup_push_simple(remote, get_current_branch(remote), 
triangular);
break;
 
case PUSH_DEFAULT_UPSTREAM:
diff --git a/remote.c b/remote.c
index 5f63d55..3437d1f 100644
--- a/remote.c
+++ b/remote.c
@@ -352,13 +352,17 @@ static int handle_config(const char *key, const char 
*value, void *cb)
explicit_default_remote_name = 1;
}
} else if (!strcmp(subkey, ".pushremote")) {
+   if (git_config_string(&branch->pushremote_name, key, 
value))
+   return -1;
if (branch == current_branch)
-   if (git_config_string(&branch_pushremote_name, 
key, value))
-   return -1;
+   branch_pushremote_name = 
xstrdup(branch->pushremote_name);
} else if (!strcmp(subkey, ".merge")) {
if (!value)
return config_error_nonbool(key);
add_merge(branch, xstrdup(value));
+   } else if (!strcmp(subkey, ".push")) {
+   if (git_config_string(&branch->push_name, key, value))
+   return -1;
}
return 0;
}
@@ -1562,6 +1566,14 @@ struct branch *branch_get(const char *name)
}
}
}
+   if (ret && ret->pushremote_name) {
+   struct remote *pushremote;
+   pushremote = pushremote_get(ret->pushremote_name);
+   ret->push.src = xstrdup(ret->push_name);
+   if (remote_find_tracking(pushremote, &ret->push)
+   && !strcmp(ret->pushremote_name, "."))
+   ret->push.dst = xstrdup(ret->push_name);
+   }
return ret;
 }
 
@@ -1771,6 +1783,15 @@ int ref_newer(const unsigned char *new_sha1, const 
unsigned char *old_sha1)
return found;
 }
 
+static char *get_base(struct branch *branch)
+{
+   if (branch->push.dst)
+   return branch->push.dst;
+   if (branch->merge && branch->merge[0] && branch->merge[0]->dst)
+   return branch->merge[0]->dst;
+   return NULL;
+}
+
 /*
  * Compare a branch with its upstream, and save their differences (number
  * of commits) in *num_ours and *num_theirs.
@@ -1788,12 +1809,13 @@ int stat_tracking_info(struct branch *branch, int 
*num_ours, int *num_theirs)
int rev_argc;
 
/* Cannot stat unless we are marked to build on top of somebody else. */
-   if (!branch ||
-   !branch->merge || !branch->merge[0] || !branch->merge[0]->dst)
+   if (!branch)
+   return 0;
+   base = get_base(branch);
+   if (!base)
return 0;
 
/* Cannot stat if what we used to build on no longer exists */
-   base = branch->merge[0]->dst;
if (read_ref(base, sha1))
return -1;
theirs = lookup_commit_reference(sha1);
@@ -1869,7 +1891,7 @@ int 

[PATCH v2 4/9] t: branch add publish branch tests

2014-04-10 Thread Felipe Contreras
Signed-off-by: Felipe Contreras 
---
 t/t3200-branch.sh | 76 +++
 1 file changed, 76 insertions(+)

diff --git a/t/t3200-branch.sh b/t/t3200-branch.sh
index fcdb867..8cd21d1 100755
--- a/t/t3200-branch.sh
+++ b/t/t3200-branch.sh
@@ -907,4 +907,80 @@ test_expect_success 'tracking with unexpected .fetch 
refspec' '
)
 '
 
+test_expect_success '--set-publish-to fails on multiple branches' '
+   test_must_fail git branch --set-publish-to master a b c
+'
+
+test_expect_success '--set-publish-to fails on detached HEAD' '
+   test_when_finished "git checkout master" &&
+   git checkout master^{} &&
+   test_must_fail git branch --set-publish-to master
+'
+
+test_expect_success '--set-publish-to fails on a missing dst branch' '
+   test_must_fail git branch --set-publish-to master does-not-exist
+'
+
+test_expect_success '--set-publish-to fails on a missing src branch' '
+   test_must_fail git branch --set-publish-to does-not-exist master
+'
+
+test_expect_success '--set-publish-to fails on a non-ref' '
+   test_must_fail git branch --set-publish-to HEAD^{}
+'
+
+test_expect_success 'use --set-publish-to modify HEAD' '
+   git checkout master &&
+   test_config branch.master.pushremote foo &&
+   test_config branch.master.push foo &&
+   git branch -f test &&
+   git branch --set-publish-to test &&
+   test "$(git config branch.master.pushremote)" = "." &&
+   test "$(git config branch.master.push)" = "refs/heads/test"
+'
+
+test_expect_success 'use --set-publish-to modify a particular branch' '
+   git branch -f test &&
+   git branch -f test2 &&
+   git branch --set-publish-to test2 test &&
+   test "$(git config branch.test.pushremote)" = "." &&
+   test "$(git config branch.test.push)" = "refs/heads/test2"
+'
+
+test_expect_success '--unset-publish should fail if given a non-existent 
branch' '
+   test_must_fail git branch --unset-publish i-dont-exist
+'
+
+test_expect_success 'test --unset-publish on HEAD' '
+   git checkout master &&
+   git branch -f test &&
+   test_config branch.master.pushremote foo &&
+   test_config branch.master.push foo &&
+   git branch --set-publish-to test &&
+   git branch --unset-publish &&
+   test_must_fail git config branch.master.pushremote &&
+   test_must_fail git config branch.master.push &&
+   # fail for a branch without publish set
+   test_must_fail git branch --unset-publish
+'
+
+test_expect_success '--unset-publish should fail on multiple branches' '
+   test_must_fail git branch --unset-publish a b c
+'
+
+test_expect_success '--unset-publish should fail on detached HEAD' '
+   test_when_finished "git checkout -" &&
+   git checkout HEAD^{} &&
+   test_must_fail git branch --unset-publish
+'
+
+test_expect_success 'test --unset-publish on a particular branch' '
+   git branch -f test &&
+   git branch -f test2 &&
+   git branch --set-publish-to test2 test &&
+   git branch --unset-publish test &&
+   test_must_fail git config branch.test2.pushremote &&
+   test_must_fail git config branch.test2.push
+'
+
 test_done
-- 
1.9.1+fc1

--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 6/9] branch: display publish branch

2014-04-10 Thread Felipe Contreras
Signed-off-by: Felipe Contreras 
---
 builtin/branch.c | 17 -
 t/t6040-tracking-info.sh |  5 +++--
 2 files changed, 19 insertions(+), 3 deletions(-)

diff --git a/builtin/branch.c b/builtin/branch.c
index 17773d7..e0a8d0a 100644
--- a/builtin/branch.c
+++ b/builtin/branch.c
@@ -42,6 +42,7 @@ static char branch_colors[][COLOR_MAXLEN] = {
GIT_COLOR_NORMAL,   /* LOCAL */
GIT_COLOR_GREEN,/* CURRENT */
GIT_COLOR_BLUE, /* UPSTREAM */
+   GIT_COLOR_YELLOW,   /* PUBLISH */
 };
 enum color_branch {
BRANCH_COLOR_RESET = 0,
@@ -49,7 +50,8 @@ enum color_branch {
BRANCH_COLOR_REMOTE = 2,
BRANCH_COLOR_LOCAL = 3,
BRANCH_COLOR_CURRENT = 4,
-   BRANCH_COLOR_UPSTREAM = 5
+   BRANCH_COLOR_UPSTREAM = 5,
+   BRANCH_COLOR_PUBLISH = 6
 };
 
 static enum merge_filter {
@@ -76,6 +78,8 @@ static int parse_branch_color_slot(const char *var, int ofs)
return BRANCH_COLOR_CURRENT;
if (!strcasecmp(var+ofs, "upstream"))
return BRANCH_COLOR_UPSTREAM;
+   if (!strcasecmp(var+ofs, "publish"))
+   return BRANCH_COLOR_PUBLISH;
return -1;
 }
 
@@ -448,6 +452,17 @@ static void fill_tracking_info(struct strbuf *stat, const 
char *branch_name,
else
strbuf_addstr(&fancy, ref);
}
+   if (branch->push.dst) {
+   ref = shorten_unambiguous_ref(branch->push.dst, 0);
+   if (fancy.len)
+   strbuf_addstr(&fancy, ", ");
+   if (want_color(branch_use_color))
+   strbuf_addf(&fancy, "%s%s%s",
+   branch_get_color(BRANCH_COLOR_PUBLISH),
+   ref, 
branch_get_color(BRANCH_COLOR_RESET));
+   else
+   strbuf_addstr(&fancy, ref);
+   }
 
if (upstream_is_gone) {
if (show_upstream_ref)
diff --git a/t/t6040-tracking-info.sh b/t/t6040-tracking-info.sh
index 7ac8fd0..8b9ef63 100755
--- a/t/t6040-tracking-info.sh
+++ b/t/t6040-tracking-info.sh
@@ -33,7 +33,8 @@ test_expect_success setup '
git checkout -b b5 --track brokenbase &&
advance g &&
git branch -d brokenbase &&
-   git checkout -b b6 origin
+   git checkout -b b6 origin &&
+   git branch --set-publish origin/master b6
) &&
git checkout -b follower --track master &&
advance h
@@ -64,7 +65,7 @@ b2 [origin/master: ahead 1, behind 1] d
 b3 [origin/master: behind 1] b
 b4 [origin/master: ahead 2] f
 b5 [brokenbase: gone] g
-b6 [origin/master] c
+b6 [origin/master, origin/master] c
 EOF
 
 test_expect_success 'branch -vv' '
-- 
1.9.1+fc1

--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 7/9] sha1_name: cleanup interpret_branch_name()

2014-04-10 Thread Felipe Contreras
The 'upstream' variable doesn't hold an "upstream", but a branch, so
make it clearer.

Signed-off-by: Felipe Contreras 
---
 sha1_name.c | 24 
 1 file changed, 12 insertions(+), 12 deletions(-)

diff --git a/sha1_name.c b/sha1_name.c
index 6fca869..906f09d 100644
--- a/sha1_name.c
+++ b/sha1_name.c
@@ -1057,31 +1057,31 @@ static void set_shortened_ref(struct strbuf *buf, const 
char *ref)
free(s);
 }
 
-static const char *get_upstream_branch(const char *branch_buf, int len)
+static const char *get_upstream_branch(const char *name_buf, int len)
 {
-   char *branch = xstrndup(branch_buf, len);
-   struct branch *upstream = branch_get(*branch ? branch : NULL);
+   char *name = xstrndup(name_buf, len);
+   struct branch *branch = branch_get(*name ? name : NULL);
 
/*
 * Upstream can be NULL only if branch refers to HEAD and HEAD
 * points to something different than a branch.
 */
-   if (!upstream)
+   if (!branch)
die(_("HEAD does not point to a branch"));
-   if (!upstream->merge || !upstream->merge[0]->dst) {
-   if (!ref_exists(upstream->refname))
-   die(_("No such branch: '%s'"), branch);
-   if (!upstream->merge) {
+   if (!branch->merge || !branch->merge[0]->dst) {
+   if (!ref_exists(branch->refname))
+   die(_("No such branch: '%s'"), name);
+   if (!branch->merge) {
die(_("No upstream configured for branch '%s'"),
-   upstream->name);
+   branch->name);
}
die(
_("Upstream branch '%s' not stored as a remote-tracking 
branch"),
-   upstream->merge[0]->src);
+   branch->merge[0]->src);
}
-   free(branch);
+   free(name);
 
-   return upstream->merge[0]->dst;
+   return branch->merge[0]->dst;
 }
 
 static int interpret_upstream_mark(const char *name, int namelen,
-- 
1.9.1+fc1

--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 8/9] sha1_name: simplify track finding

2014-04-10 Thread Felipe Contreras
It's more efficient to check for the braces first.

Signed-off-by: Felipe Contreras 
---
 sha1_name.c | 11 +++
 1 file changed, 7 insertions(+), 4 deletions(-)

diff --git a/sha1_name.c b/sha1_name.c
index 906f09d..aa3f3e0 100644
--- a/sha1_name.c
+++ b/sha1_name.c
@@ -417,7 +417,7 @@ static int ambiguous_path(const char *path, int len)
 
 static inline int upstream_mark(const char *string, int len)
 {
-   const char *suffix[] = { "@{upstream}", "@{u}" };
+   const char *suffix[] = { "upstream", "u" };
int i;
 
for (i = 0; i < ARRAY_SIZE(suffix); i++) {
@@ -475,7 +475,7 @@ static int get_sha1_basic(const char *str, int len, 
unsigned char *sha1)
nth_prior = 1;
continue;
}
-   if (!upstream_mark(str + at, len - at)) {
+   if (!upstream_mark(str + at + 2, len - at - 3)) 
{
reflog_len = (len-1) - (at+2);
len = at;
}
@@ -1089,7 +1089,10 @@ static int interpret_upstream_mark(const char *name, int 
namelen,
 {
int len;
 
-   len = upstream_mark(name + at, namelen - at);
+   if (name[at + 1] != '{' || name[namelen - 1] != '}')
+   return -1;
+
+   len = upstream_mark(name + at + 2, namelen - at - 3);
if (!len)
return -1;
 
@@ -1097,7 +1100,7 @@ static int interpret_upstream_mark(const char *name, int 
namelen,
return -1;
 
set_shortened_ref(buf, get_upstream_branch(name, at));
-   return len + at;
+   return len + at + 3;
 }
 
 /*
-- 
1.9.1+fc1

--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 5/9] push: add --set-publish option

2014-04-10 Thread Felipe Contreras
To setup publish tracking branch, like 'git branch --set-publish'.

Signed-off-by: Felipe Contreras 
---
 Documentation/git-push.txt |  9 +-
 builtin/push.c |  2 ++
 t/t5529-push-publish.sh| 70 ++
 transport.c| 28 +--
 transport.h|  1 +
 5 files changed, 100 insertions(+), 10 deletions(-)
 create mode 100755 t/t5529-push-publish.sh

diff --git a/Documentation/git-push.txt b/Documentation/git-push.txt
index 2b7f4f9..bf6ff9c 100644
--- a/Documentation/git-push.txt
+++ b/Documentation/git-push.txt
@@ -10,7 +10,8 @@ SYNOPSIS
 
 [verse]
 'git push' [--all | --mirror | --tags] [--follow-tags] [-n | --dry-run] 
[--receive-pack=]
-  [--repo=] [-f | --force] [--prune] [-v | --verbose] [-u 
| --set-upstream]
+  [--repo=] [-f | --force] [--prune] [-v | --verbose]
+  [-u | --set-upstream] [-p | --set-publish]
   [--force-with-lease[=[:]]]
   [--no-verify] [ [...]]
 
@@ -231,6 +232,12 @@ useful if you write an alias or script around 'git push'.
linkgit:git-pull[1] and other commands. For more information,
see 'branch..merge' in linkgit:git-config[1].
 
+-p::
+--set-publish::
+   For every branch that is up to date or successfully pushed, add
+   publish branch tracking reference, used by argument-less
+   linkgit:git-pull[1] and other commands.
+
 --[no-]thin::
These options are passed to linkgit:git-send-pack[1]. A thin transfer
significantly reduces the amount of sent data when the sender and
diff --git a/builtin/push.c b/builtin/push.c
index a1fdc49..9e61b8f 100644
--- a/builtin/push.c
+++ b/builtin/push.c
@@ -532,6 +532,8 @@ int cmd_push(int argc, const char **argv, const char 
*prefix)
OPT_STRING( 0 , "exec", &receivepack, "receive-pack", 
N_("receive pack program")),
OPT_BIT('u', "set-upstream", &flags, N_("set upstream for git 
pull/status"),
TRANSPORT_PUSH_SET_UPSTREAM),
+   OPT_BIT('p', "set-publish", &flags, N_("set publish for git 
pull/status"),
+   TRANSPORT_PUSH_SET_PUBLISH),
OPT_BOOL(0, "progress", &progress, N_("force progress 
reporting")),
OPT_BIT(0, "prune", &flags, N_("prune locally removed refs"),
TRANSPORT_PUSH_PRUNE),
diff --git a/t/t5529-push-publish.sh b/t/t5529-push-publish.sh
new file mode 100755
index 000..2037026
--- /dev/null
+++ b/t/t5529-push-publish.sh
@@ -0,0 +1,70 @@
+#!/bin/sh
+
+test_description='push with --set-publish'
+
+. ./test-lib.sh
+
+test_expect_success 'setup bare parent' '
+   git init --bare parent &&
+   git remote add publish parent
+'
+
+test_expect_success 'setup local commit' '
+   echo content >file &&
+   git add file &&
+   git commit -m one
+'
+
+check_config() {
+   (echo $2; echo $3) >expect.$1
+   (git config branch.$1.pushremote
+git config branch.$1.push) >actual.$1
+   test_cmp expect.$1 actual.$1
+}
+
+test_expect_success 'push -p master:master' '
+   git push -p publish master:master &&
+   check_config master publish refs/heads/master
+'
+
+test_expect_success 'push -u master:other' '
+   git push -p publish master:other &&
+   check_config master publish refs/heads/other
+'
+
+test_expect_success 'push -p --dry-run master:otherX' '
+   git push -p --dry-run publish master:otherX &&
+   check_config master publish refs/heads/other
+'
+
+test_expect_success 'push -p master2:master2' '
+   git branch master2 &&
+   git push -p publish master2:master2 &&
+   check_config master2 publish refs/heads/master2
+'
+
+test_expect_success 'push -p master2:other2' '
+   git push -p publish master2:other2 &&
+   check_config master2 publish refs/heads/other2
+'
+
+test_expect_success 'push -p :master2' '
+   git push -p publish :master2 &&
+   check_config master2 publish refs/heads/other2
+'
+
+test_expect_success 'push -u --all' '
+   git branch all1 &&
+   git branch all2 &&
+   git push -p --all &&
+   check_config all1 publish refs/heads/all1 &&
+   check_config all2 publish refs/heads/all2
+'
+
+test_expect_success 'push -p HEAD' '
+   git checkout -b headbranch &&
+   git push -p publish HEAD &&
+   check_config headbranch publish refs/heads/headbranch
+'
+
+t

[PATCH v2 9/9] sha1_name: add support for @{publish} marks

2014-04-10 Thread Felipe Contreras
Signed-off-by: Felipe Contreras 
---
 Documentation/revisions.txt |  4 
 sha1_name.c | 49 -
 t/t1508-at-combinations.sh  |  5 +
 3 files changed, 40 insertions(+), 18 deletions(-)

diff --git a/Documentation/revisions.txt b/Documentation/revisions.txt
index 5a286d0..fd01cb4 100644
--- a/Documentation/revisions.txt
+++ b/Documentation/revisions.txt
@@ -96,6 +96,10 @@ some output processing may assume ref names in UTF-8.
   refers to the branch that the branch specified by branchname is set to build 
on
   top of.  A missing branchname defaults to the current one.
 
+'@\{publish\}', e.g. 'master@\{publish\}', '@\{p\}'::
+  The suffix '@\{publish\}' to a branchname refers to the remote branch to
+  push to. A missing branchname defaults to the current one.
+
 '{caret}', e.g. 'HEAD{caret}, v1.5.1{caret}0'::
   A suffix '{caret}' to a revision parameter means the first parent of
   that commit object.  '{caret}' means the th parent (i.e.
diff --git a/sha1_name.c b/sha1_name.c
index aa3f3e0..a36852d 100644
--- a/sha1_name.c
+++ b/sha1_name.c
@@ -415,9 +415,9 @@ static int ambiguous_path(const char *path, int len)
return slash;
 }
 
-static inline int upstream_mark(const char *string, int len)
+static inline int tracking_mark(const char *string, int len)
 {
-   const char *suffix[] = { "upstream", "u" };
+   const char *suffix[] = { "upstream", "u", "publish", "p" };
int i;
 
for (i = 0; i < ARRAY_SIZE(suffix); i++) {
@@ -475,7 +475,7 @@ static int get_sha1_basic(const char *str, int len, 
unsigned char *sha1)
nth_prior = 1;
continue;
}
-   if (!upstream_mark(str + at + 2, len - at - 3)) 
{
+   if (!tracking_mark(str + at + 2, len - at - 3)) 
{
reflog_len = (len-1) - (at+2);
len = at;
}
@@ -1057,10 +1057,11 @@ static void set_shortened_ref(struct strbuf *buf, const 
char *ref)
free(s);
 }
 
-static const char *get_upstream_branch(const char *name_buf, int len)
+static const char *get_tracking_branch(const char *name_buf, int len, char 
type)
 {
char *name = xstrndup(name_buf, len);
struct branch *branch = branch_get(*name ? name : NULL);
+   char *tracking = NULL;
 
/*
 * Upstream can be NULL only if branch refers to HEAD and HEAD
@@ -1068,23 +1069,35 @@ static const char *get_upstream_branch(const char 
*name_buf, int len)
 */
if (!branch)
die(_("HEAD does not point to a branch"));
-   if (!branch->merge || !branch->merge[0]->dst) {
-   if (!ref_exists(branch->refname))
-   die(_("No such branch: '%s'"), name);
-   if (!branch->merge) {
-   die(_("No upstream configured for branch '%s'"),
-   branch->name);
+   switch (type) {
+   case 'u':
+   if (!branch->merge || !branch->merge[0]->dst) {
+   if (!ref_exists(branch->refname))
+   die(_("No such branch: '%s'"), name);
+   if (!branch->merge) {
+   die(_("No upstream configured for branch '%s'"),
+   branch->name);
+   }
+   die(
+   _("Upstream branch '%s' not stored as a 
remote-tracking branch"),
+   branch->merge[0]->src);
+   }
+   tracking = branch->merge[0]->dst;
+   break;
+   case 'p':
+   if (!branch->push.dst) {
+   die(_("No publish configured for branch '%s'"),
+   branch->name);
}
-   die(
-   _("Upstream branch '%s' not stored as a remote-tracking 
branch"),
-   branch->merge[0]->src);
+   tracking = branch->push.dst;
+   break;
}
free(name);
 
-   return branch->merge[0]->dst;
+   return tracking;
 }
 
-static int interpret_upstream_mark(const char *name, int namelen,
+static int interpret_tracking_mark(const char *name, int namelen,
   int at, struct strbuf *buf)
 {
int len;
@@ -1092,14 +1105,14 @@ static

Re: [PATCH 2/2] format-patch: introduce format.defaultTo

2014-04-10 Thread Felipe Contreras
Ramkumar Ramachandra wrote:
> We already have a branch.*.pushremote, and I don't see the value of
> branch.*.pushbranch (what you're referring to as pushupstream, I assume)
> except for Gerrit users. Frankly, I don't use full triangular workflows
> myself mainly because my prompt is compromised: when I have a branch.*.remote
> different from branch.*.pushremote, I'd like to see where my branch is with
> respect to @{u} and @{publish} (not yet invented);

@{publish} not yet invented? I sent this back in October:

http://article.gmane.org/gmane.comp.version-control.git/235981

-- 
Felipe Contreras
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 2/2] format-patch: introduce format.defaultTo

2014-04-10 Thread Felipe Contreras
Ramkumar Ramachandra wrote:
> My primary concern is that the proposed @{publish} should be a first-class
> citizen; if it has everything that @{u} has, then we're both good: you'd
> primarily use @{u}, while I'd primarily use @{publish}.

Something like this?

http://article.gmane.org/gmane.comp.version-control.git/246038

-- 
Felipe Contreras
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2 9/9] sha1_name: add support for @{publish} marks

2014-04-10 Thread Felipe Contreras
Ramkumar Ramachandra wrote:
> Felipe Contreras wrote:
> > @@ -1068,23 +1069,35 @@ static const char *get_upstream_branch(const char 
> > *name_buf, int len)
> >  */
> > if (!branch)
> > die(_("HEAD does not point to a branch"));
> > -   if (!branch->merge || !branch->merge[0]->dst) {
> > -   if (!ref_exists(branch->refname))
> > -   die(_("No such branch: '%s'"), name);
> > -   if (!branch->merge) {
> > -   die(_("No upstream configured for branch '%s'"),
> > -   branch->name);
> > +   switch (type) {
> > +   case 'u':
> > +   if (!branch->merge || !branch->merge[0]->dst) {
> > +   if (!ref_exists(branch->refname))
> > +   die(_("No such branch: '%s'"), name);
> > +   if (!branch->merge) {
> > +   die(_("No upstream configured for branch 
> > '%s'"),
> > +   branch->name);
> > +   }
> > +   die(
> > +   _("Upstream branch '%s' not stored as a 
> > remote-tracking branch"),
> > +   branch->merge[0]->src);
> > +   }
> > +   tracking = branch->merge[0]->dst;
> > +   break;
> > +   case 'p':
> > +   if (!branch->push.dst) {
> > +   die(_("No publish configured for branch '%s'"),
> > +   branch->name);
> 
> This assumes a push.default value of 'current' or 'matching'. What
> happens if push.default is set to 'nothing' or 'upstream', for
> instance?

Why would that matter? @{upstream} doesn't depend on this, neither does
@{publish}; @{upstream} is .remote+.merge, @{publish} is .pushremote+.push.

If the user hasn't configured a publish branch, @{publish} fails.

-- 
Felipe Contreras
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2 8/9] sha1_name: simplify track finding

2014-04-10 Thread Felipe Contreras
Ramkumar Ramachandra wrote:
> Felipe Contreras wrote:
> > It's more efficient to check for the braces first.
> 
> Why is it more efficient? So you can error out quickly in the case of
> a malformed string?

That's one reason. The other is that get_sha1_basic() calls upstream_mark()
when we _already_ know there's a @{foo}.

-- 
Felipe Contreras
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2 9/9] sha1_name: add support for @{publish} marks

2014-04-10 Thread Felipe Contreras
Ramkumar Ramachandra wrote:
> Felipe Contreras wrote:
> > diff --git a/sha1_name.c b/sha1_name.c
> > index aa3f3e0..a36852d 100644
> > --- a/sha1_name.c
> > +++ b/sha1_name.c
> > @@ -415,9 +415,9 @@ static int ambiguous_path(const char *path, int len)
> > return slash;
> >  }
> >
> > -static inline int upstream_mark(const char *string, int len)
> > +static inline int tracking_mark(const char *string, int len)
> >  {
> > -   const char *suffix[] = { "upstream", "u" };
> > +   const char *suffix[] = { "upstream", "u", "publish", "p" };
> 
> Oh, another thing: on some threads, people decided that "@{push}"
> would be a more apt name (+ alias @{u} to @{pull} for symmetry).

@{push} is the name I originally suggested, but it's weird to talk about
"the push branch", so I decided on "the publish branch", which is more natural.

-- 
Felipe Contreras
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2 6/9] branch: display publish branch

2014-04-10 Thread Felipe Contreras
Ramkumar Ramachandra wrote:
> Felipe Contreras wrote:
> > Signed-off-by: Felipe Contreras 
> 
> Please write a commit message, preferably showing the new git-branch output.

Yeah... this has been sitting in git-fc for quite a while, I wasn't expecting
to send this patch series again given that nobody commented on v1.

> I noticed that this only picks up a publish-branch if
> branch.*.pushremote is configured. What happened to the case when
> remote.pushdefault is configured?

What happens when branch.*.remote is not configured for @{upstream}? The same
thing.

It might be useful to visualize what would be the name of the branch when
pushing it (without a refspec) even if the publish branch hasn't been
configured, but I think the code would be much more coplicated, and it would
break symetry with @{upstream}, besides, the user can just do 'git push -p
branch', and from that moment on it will be visible.

-- 
Felipe Contreras
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: Our official home page and logo for the Git project

2014-04-11 Thread Felipe Contreras
Jeff King wrote:
> On Thu, Apr 10, 2014 at 10:24:24AM +1000, Andrew Ardill wrote:
> 
> > It's normal for an organisation to have a collection of logos to
> > choose from, with one 'official' version. For example, a black and
> > white version is useful for print. Similarly, it's useful to have a
> > couple of different contrast level/colours that can be used in the
> > appropriate situations.
> 
> There are a few options at
> 
>   http://git-scm.com/downloads/logos
> 
> for matching the logo to the background.

That doesn't change the fact that bright red is a horrible color, and
that bright red is used *by default*, as you can see here[1].

Moreover, even the black ones have the issue I already mentioned; they
picture the equivalent of two root commits (with no parents) that are
immediately merged, and the history continues, but who is interested in
the initial commits? And who has multiple root commits? No one.

I am willing to bet whomever designed this logo had never used Git in
his life.

My version of the logo is the equivalent of to head commits that diverge
from a common one, which is extremely common; everybody works on the
latest commits, and has multiple branches.

This is so obvious and simple, that I bet nobody even bother to analize
the logo, they all though "OK, I'm not a designer, it's a logo,
anything's fine for me".

Secondly, the logos that are not black, are bright red, which is
horrible; not only do they look bad in almost every situation due to the
contrast, but in a Git's mindeset red implies old, a minus, the hunk
removed, an error, which is not good. Even in the old logos[2] (whick
even gitk is using), there was always a "-" represented in red.

In my version green is used instead, which represent progress, a plus,
the hunk added, success.

> > There is nothing wrong with having alternates that have been approved
> > for various situations.
> 
> I'm not sure if this is how you meant it, but I want to emphasize that
> there is no "approval" necessary for using alternate logos. Saying
> "let's recognize this one as an official logo" is not meant to shut down
> the use of others. It is only meant to say "when people ask for an
> official logo (e.g., GSoC does so), this one is a good answer".

Yes, but that doesn't mean we should shut down our brains and just
accept anything as the main official logo (of which most of the
alternates would be based on).

I would actually like you (everyone) to be honest and answer this
question;

Have you actually analized the logo? Or are you just arguing against
change, because the logo is already used by git-scm.com, and related
stuff?

[1] http://felipec.org/contrast.png
[2] http://git-osx-installer.googlecode.com/files/GitLogo.jpg

-- 
Felipe Contreras
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: Our official home page and logo for the Git project

2014-04-11 Thread Felipe Contreras
Max Horn wrote:
> As for the logo, I think it's nice and simple,

You don't think red represent an oldness in Git? Whereas green
represents progress?

> and based on experience I think that for every logo you'll find people
> who object to it.

So we should just accept any logo without thinking about it?

> E.g. the red color of the log on git-scm.com looks great to me, while
> I dislike e.g. the color variation Felipe is using.

If you don't like my variation that doesn't mean we should accept the
red one; there are many shades of green to begin with.

Also, there's more than the color to think about; look at the order of
the pictured commits; they don't make any sense.

-- 
Felipe Contreras
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2 6/9] branch: display publish branch

2014-04-11 Thread Felipe Contreras
Jeff King wrote:
> On Thu, Apr 10, 2014 at 05:36:59PM -0500, Felipe Contreras wrote:
> 
> > > I noticed that this only picks up a publish-branch if
> > > branch.*.pushremote is configured. What happened to the case when
> > > remote.pushdefault is configured?
> > 
> > What happens when branch.*.remote is not configured for @{upstream}? The 
> > same
> > thing.
> 
> I don't know if that is a good comparison.

I think it is. @{publish} is like @{upstream}. Period.

> In other threads, the discussed meaning of @{publish} was something like
> "the tracking branch of the ref you would push to if you ran 'git push'
> without arguments".

And I disagree.

> That is consistent with @{upstream} being "the tracking branch of the
> ref you would pull from with 'git pull'". But "git pull" without a
> branch.*.remote will do nothing, so "what pull would do" is the same as
> "what you have configured in your branch.*.remote".
> 
> Whereas "git push" does not depend on having branch.*.pushremote
> configured. Its behavior is based on push.default and push refspecs, so
> "what push would do" must take that into account.

Yes, but we are not talking about 'git push', we are talking about
@{publish}.

I think of @{publish} as "the branch the user has configured to push
to"; it overrides all other configurations (push.default and push
refspecs). I wouldn't mind having a @{push} *in addition* to @{publish}
that would have the behavior you mention, but for @{publish} I'm pretty
certain the behavior I want is that it maps *directly* to what the user
has configured.

Similarly, I don't want 'git branch -vv' to show @{push}; it would be a
mess to show something on all the branches, probably origin/$branch, and
probably all "ahead/behind". I want it to show @{publish}, so only the
branches the user has *explicitly* configured.

> > It might be useful to visualize what would be the name of the branch when
> > pushing it (without a refspec) even if the publish branch hasn't been
> > configured, but I think the code would be much more coplicated, and it would
> > break symetry with @{upstream}, besides, the user can just do 'git push -p
> > branch', and from that moment on it will be visible.
> 
> It is more complicated (see the patches that Junio had at
> jk/branch-at-publish), but I think it is more likely to do what the user
> expects.
> 
> For instance, it looks like your @{publish} requires config like:
> 
>   [branch "master"]
>   pushremote = foo
>   push = refs/heads/bar
> 
> to operate. Setting "pushremote" affects what "git push" does; it will
> go to the "foo" remote. But the branch.master.push setting does not do
> anything to "git push". Only a push refspec (or push.default setting)
> will change that. So the "branch.*.push" must be kept in sync manually
> (perhaps by running "git push -p").
> 
> Whereas if @{publish} means "where you would push to"

It doesn't mean that to me.

For the record, I've been thinking about this for a long long time, and
I argued for @{push} and @{publish} long before you discussed this in
January (which apparently you forgot). I implemented this more than half
a year ago, and have been using it since; it works great. The problem of
triangular workflows is pretty much solved for me.

-- 
Felipe Contreras
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2 0/9] Introduce publish tracking branch

2014-04-11 Thread Felipe Contreras
Matthieu Moy wrote:
> Felipe Contreras  writes:
> 
> > As it has been discussed before, our support for triangular workflows is
> > lacking, and the following patch series aims to improve that situation.
> 
> I'm not a heavy user of triangular workflow, so I'm not in the best
> position to comment (and I have no time for a real review, sorry).
> 
> On overall, I do like the change. I played a bit with it, and do not
> understand what "git push" does:
> 
>   $ git status
>   On branch master
>   Your branch is ahead of 'origin/new' by 4 commits.
> (use "git push" to publish your local commits)
> 
> => OK, it's using the publish branch to tell me whether I should push.
> 
>   $ git push -v
>   Pushing to /tmp/git
>   To /tmp/git
>= [up to date]  master -> master
>   updating local tracking ref 'refs/remotes/origin/master'
>   Everything up-to-date
> 
> => Err, it still pushes to the upstream branch ... Wasn't that the point
> of the change to push to publish? Did I do something wrong?

My patch series only affects push.default=simple, perhaps you have a
different configuration.

Maybe we want the publish branch to override any push.default, so:

--- a/builtin/push.c
+++ b/builtin/push.c
@@ -195,11 +195,7 @@ static void setup_push_current(struct remote *remote, 
struct branch *branch)
 static void setup_push_simple(struct remote *remote, struct branch *branch,
int triangular)
 {
-   if (branch->push_name) {
-   struct strbuf refspec = STRBUF_INIT;
-   strbuf_addf(&refspec, "%s:%s", branch->name, branch->push_name);
-   add_refspec(refspec.buf);
-   } else if (triangular) {
+   if (triangular) {
setup_push_current(remote, branch);
} else {
setup_push_upstream(remote, branch, triangular);
@@ -260,8 +256,16 @@ static struct branch *get_current_branch(struct remote 
*remote)
 
 static void setup_default_push_refspecs(struct remote *remote)
 {
+   struct branch *branch = branch_get(NULL);
int triangular = is_workflow_triangular(remote);
 
+   if (branch && branch->push_name) {
+   struct strbuf refspec = STRBUF_INIT;
+   strbuf_addf(&refspec, "%s:%s", branch->name, branch->push_name);
+   add_refspec(refspec.buf);
+   return;
+   }
+
switch (push_default) {
default:
case PUSH_DEFAULT_UNSPECIFIED:

-- 
Felipe Contreras
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: Our official home page and logo for the Git project

2014-04-11 Thread Felipe Contreras
Max Horn wrote:
> On 11.04.2014, at 15:29, Felipe Contreras  wrote:
> > Max Horn wrote:
> > 
> > You don't think red represent an oldness in Git? Whereas green
> > represents progress?
> 
> No, I don't think that.

Then you belong to the minority of Git users. Those of us that see
patches day and night, red is old, green is new.

> >> and based on experience I think that for every logo you'll find people
> >> who object to it.
> > 
> > So we should just accept any logo without thinking about it?
> 
> No. You (well, everybody) should just take a deep breath, step back,
> and ask yourself "Does this really matter that much to me and the rest
> of the world? Is it worth keeping up another long drawn discussion? Is
> there perhaps a chance for a compromise?"

So your position is "it really doesn't matter". Noted.

-- 
Felipe Contreras
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: Our official home page and logo for the Git project

2014-04-11 Thread Felipe Contreras
Vincent van Ravesteijn wrote:
> On Fri, Apr 11, 2014 at 3:24 PM, Felipe Contreras
>  wrote:
> >
> > Moreover, even the black ones have the issue I already mentioned; they
> > picture the equivalent of two root commits (with no parents) that are
> > immediately merged, and the history continues, but who is interested in
> > the initial commits? And who has multiple root commits? No one.
> 
> [..]
> 
> > My version of the logo is the equivalent of to head commits that diverge
> > from a common one, which is extremely common; everybody works on the
> > latest commits, and has multiple branches.
> >
> 
> The red logo looks like a merge to me, and a merge with master means
> 'success' to me.

A merge of what? Two commits without parents? Is that normal?

-- 
Felipe Contreras
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: Our official home page and logo for the Git project

2014-04-11 Thread Felipe Contreras
Holger Hellmuth wrote:
> Am 11.04.2014 17:39, schrieb Philippe Vaucher:
> >FWIW, I think if you made a poll and asked which color is the most
> >"positive" between green and red, the vast majority of people would
> >say "green". Examples could be traffic green lights vs red lights, or
> 
> Coca-Cola uses red. So red is refreshing and hip (if you believe the
> commercials).

Coca-Cola chose red long time ago, if branding and artist experts told
them another colour would be better it wouldn't matter; their color is
red and they can't change it now.

Moreover we are not in the business of refreshing beverages, we are in
the business of revision control, and in revision control red is old,
green is new. Period.

> Which is to say, git's wellfare will surely not depend on the color of
> its logo. Otherwise the Coca-Cola company would have used a different
> color.

It doesn't. But green is still better.

-- 
Felipe Contreras
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3 2/8] Add concept of 'publish' branch

2014-04-11 Thread Felipe Contreras
The publish branch is the branch the user wants to push to, akin to the
upstream branch, which is the branch the user wants to use as a
baseline. It overrides other configurations, such as push.default, and
remote..push.

The upstream branch is:

  branch.$name.remote
  branch.$name.merge

The publish branch is:

  branch.$name.pushremote
  branch.$name.push

Signed-off-by: Felipe Contreras 
---
 Documentation/config.txt |  7 ++
 builtin/push.c   |  9 ++-
 remote.c | 34 +-
 remote.h |  4 
 t/t5516-fetch-push.sh| 62 
 5 files changed, 109 insertions(+), 7 deletions(-)

diff --git a/Documentation/config.txt b/Documentation/config.txt
index 5f4d793..1569353 100644
--- a/Documentation/config.txt
+++ b/Documentation/config.txt
@@ -764,6 +764,13 @@ branch..mergeoptions::
option values containing whitespace characters are currently not
supported.
 
+branch..push::
+   Defines, together with branch..pushremote, the publish branch for
+   the given branch. It tells 'git push' which branch to push to, and
+   overrides any other configurations, such as push.default. It also tells
+   commands such as 'git status' and 'git branch' which remote branch to
+   use for tracking information (commits ahead and behind).
+
 branch..rebase::
When true, rebase the branch  on top of the fetched branch,
instead of merging the default branch from the default remote when
diff --git a/builtin/push.c b/builtin/push.c
index 0e50ddb..2a78c2b 100644
--- a/builtin/push.c
+++ b/builtin/push.c
@@ -441,7 +441,14 @@ static int do_push(const char *repo, int flags)
}
 
if (!refspec && !(flags & TRANSPORT_PUSH_ALL)) {
-   if (remote->push_refspec_nr) {
+   struct branch *branch = branch_get(NULL);
+   /* Is there a publish branch */
+   if (branch->pushremote_name && !strcmp(remote->name, 
branch->pushremote_name) &&
+   branch && branch->push_name) {
+   struct strbuf refspec = STRBUF_INIT;
+   strbuf_addf(&refspec, "%s:%s", branch->name, 
branch->push_name);
+   add_refspec(refspec.buf);
+   } else if (remote->push_refspec_nr) {
refspec = remote->push_refspec;
refspec_nr = remote->push_refspec_nr;
} else if (!(flags & TRANSPORT_PUSH_MIRROR))
diff --git a/remote.c b/remote.c
index 5f63d55..eda6192 100644
--- a/remote.c
+++ b/remote.c
@@ -352,13 +352,17 @@ static int handle_config(const char *key, const char 
*value, void *cb)
explicit_default_remote_name = 1;
}
} else if (!strcmp(subkey, ".pushremote")) {
+   if (git_config_string(&branch->pushremote_name, key, 
value))
+   return -1;
if (branch == current_branch)
-   if (git_config_string(&branch_pushremote_name, 
key, value))
-   return -1;
+   branch_pushremote_name = 
xstrdup(branch->pushremote_name);
} else if (!strcmp(subkey, ".merge")) {
if (!value)
return config_error_nonbool(key);
add_merge(branch, xstrdup(value));
+   } else if (!strcmp(subkey, ".push")) {
+   if (git_config_string(&branch->push_name, key, value))
+   return -1;
}
return 0;
}
@@ -1562,6 +1566,14 @@ struct branch *branch_get(const char *name)
}
}
}
+   if (ret && ret->pushremote_name && ret->push_name) {
+   struct remote *pushremote;
+   pushremote = pushremote_get(ret->pushremote_name);
+   ret->push.src = xstrdup(ret->push_name);
+   if (remote_find_tracking(pushremote, &ret->push)
+   && !strcmp(ret->pushremote_name, "."))
+   ret->push.dst = xstrdup(ret->push_name);
+   }
return ret;
 }
 
@@ -1771,6 +1783,15 @@ int ref_newer(const unsigned char *new_sha1, const 
unsigned char *old_sha1)
return found;
 }
 
+static char *get_base(struct branch *branch)
+{
+   if (branch->push.dst)
+   return branch->push.dst;
+   if (branch->merge && branch->merge[0] && branch->merge[0]->dst)
+   return branch->merge[0]->dst;
+   return NULL;
+}
+
 /*

[PATCH v3 4/8] push: add --set-publish option

2014-04-11 Thread Felipe Contreras
To setup publish tracking branch, like 'git branch --set-publish'.

Signed-off-by: Felipe Contreras 
---
 Documentation/git-push.txt |  9 +-
 builtin/push.c |  2 ++
 t/t5534-push-publish.sh| 70 ++
 transport.c| 28 +--
 transport.h|  1 +
 5 files changed, 100 insertions(+), 10 deletions(-)
 create mode 100755 t/t5534-push-publish.sh

diff --git a/Documentation/git-push.txt b/Documentation/git-push.txt
index 2b7f4f9..bf6ff9c 100644
--- a/Documentation/git-push.txt
+++ b/Documentation/git-push.txt
@@ -10,7 +10,8 @@ SYNOPSIS
 
 [verse]
 'git push' [--all | --mirror | --tags] [--follow-tags] [-n | --dry-run] 
[--receive-pack=]
-  [--repo=] [-f | --force] [--prune] [-v | --verbose] [-u 
| --set-upstream]
+  [--repo=] [-f | --force] [--prune] [-v | --verbose]
+  [-u | --set-upstream] [-p | --set-publish]
   [--force-with-lease[=[:]]]
   [--no-verify] [ [...]]
 
@@ -231,6 +232,12 @@ useful if you write an alias or script around 'git push'.
linkgit:git-pull[1] and other commands. For more information,
see 'branch..merge' in linkgit:git-config[1].
 
+-p::
+--set-publish::
+   For every branch that is up to date or successfully pushed, add
+   publish branch tracking reference, used by argument-less
+   linkgit:git-pull[1] and other commands.
+
 --[no-]thin::
These options are passed to linkgit:git-send-pack[1]. A thin transfer
significantly reduces the amount of sent data when the sender and
diff --git a/builtin/push.c b/builtin/push.c
index 2a78c2b..172e843 100644
--- a/builtin/push.c
+++ b/builtin/push.c
@@ -525,6 +525,8 @@ int cmd_push(int argc, const char **argv, const char 
*prefix)
OPT_STRING( 0 , "exec", &receivepack, "receive-pack", 
N_("receive pack program")),
OPT_BIT('u', "set-upstream", &flags, N_("set upstream for git 
pull/status"),
TRANSPORT_PUSH_SET_UPSTREAM),
+   OPT_BIT('p', "set-publish", &flags, N_("set publish for git 
pull/status"),
+   TRANSPORT_PUSH_SET_PUBLISH),
OPT_BOOL(0, "progress", &progress, N_("force progress 
reporting")),
OPT_BIT(0, "prune", &flags, N_("prune locally removed refs"),
TRANSPORT_PUSH_PRUNE),
diff --git a/t/t5534-push-publish.sh b/t/t5534-push-publish.sh
new file mode 100755
index 000..2037026
--- /dev/null
+++ b/t/t5534-push-publish.sh
@@ -0,0 +1,70 @@
+#!/bin/sh
+
+test_description='push with --set-publish'
+
+. ./test-lib.sh
+
+test_expect_success 'setup bare parent' '
+   git init --bare parent &&
+   git remote add publish parent
+'
+
+test_expect_success 'setup local commit' '
+   echo content >file &&
+   git add file &&
+   git commit -m one
+'
+
+check_config() {
+   (echo $2; echo $3) >expect.$1
+   (git config branch.$1.pushremote
+git config branch.$1.push) >actual.$1
+   test_cmp expect.$1 actual.$1
+}
+
+test_expect_success 'push -p master:master' '
+   git push -p publish master:master &&
+   check_config master publish refs/heads/master
+'
+
+test_expect_success 'push -u master:other' '
+   git push -p publish master:other &&
+   check_config master publish refs/heads/other
+'
+
+test_expect_success 'push -p --dry-run master:otherX' '
+   git push -p --dry-run publish master:otherX &&
+   check_config master publish refs/heads/other
+'
+
+test_expect_success 'push -p master2:master2' '
+   git branch master2 &&
+   git push -p publish master2:master2 &&
+   check_config master2 publish refs/heads/master2
+'
+
+test_expect_success 'push -p master2:other2' '
+   git push -p publish master2:other2 &&
+   check_config master2 publish refs/heads/other2
+'
+
+test_expect_success 'push -p :master2' '
+   git push -p publish :master2 &&
+   check_config master2 publish refs/heads/other2
+'
+
+test_expect_success 'push -u --all' '
+   git branch all1 &&
+   git branch all2 &&
+   git push -p --all &&
+   check_config all1 publish refs/heads/all1 &&
+   check_config all2 publish refs/heads/all2
+'
+
+test_expect_success 'push -p HEAD' '
+   git checkout -b headbranch &&
+   git push -p publish HEAD &&
+   check_config headbranch publish refs/heads/headbranch
+'
+
+t

[PATCH v3 1/8] t5516 (fetch-push): fix test restoration

2014-04-11 Thread Felipe Contreras
We shouldn't modify the commits; it screws the following tests.

Signed-off-by: Felipe Contreras 
---
 t/t5516-fetch-push.sh | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/t/t5516-fetch-push.sh b/t/t5516-fetch-push.sh
index 67e0ab3..f4cf0db 100755
--- a/t/t5516-fetch-push.sh
+++ b/t/t5516-fetch-push.sh
@@ -1261,6 +1261,8 @@ test_expect_success 'push --follow-tag only pushes 
relevant tags' '
 '
 
 test_expect_success 'push --no-thin must produce non-thin pack' '
+   test_when_finished "git reset --hard v1.0" &&
+
cat >>path1 <<\EOF &&
 keep base version of path1 big enough, compared to the new changes
 later, in order to pass size heuristics in
-- 
1.9.1+fc1

--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3 0/8] Introduce publish tracking branch

2014-04-11 Thread Felipe Contreras
27; '
+   mk_test up_repo heads/master &&
+   mk_test down_repo heads/master &&
+   test_config remote.up.url up_repo &&
+   test_config remote.down.url down_repo &&
+   test_config branch.master.pushremote down &&
+   test_config branch.master.push for-john &&
+   git push up &&
+   check_push_result up_repo $the_commit heads/master &&
+   check_push_result down_repo $the_first_commit heads/master
+'
+
+test_expect_success 'push with publish branch with pushdefault' '
+   mk_test up_repo heads/master &&
+   mk_test down_repo heads/master &&
+   test_config remote.up.url up_repo &&
+   test_config remote.down.url down_repo &&
+   test_config remote.pushdefault up &&
+   test_config branch.master.pushremote down &&
+   test_config branch.master.push for-john &&
+   git push &&
+   check_push_result up_repo $the_first_commit heads/master &&
+   check_push_result down_repo $the_commit heads/for-john
+'
+
+test_expect_success 'push with publish branch with remote refspec' '
+   mk_test up_repo heads/master &&
+   mk_test down_repo heads/master &&
+   test_config remote.up.url up_repo &&
+   test_config remote.down.url down_repo &&
+   test_config remote.down.push refs/heads/master:refs/heads/bad &&
+   test_config branch.master.pushremote down &&
+   test_config branch.master.push for-john &&
+   git push &&
+   check_push_result up_repo $the_first_commit heads/master &&
+   check_push_result down_repo $the_commit heads/for-john
+'
+
+test_expect_success 'push with publish branch with manual refspec' '
+   mk_test up_repo heads/master &&
+   mk_test down_repo heads/master &&
+   test_config remote.up.url up_repo &&
+   test_config remote.down.url down_repo &&
+   test_config branch.master.pushremote down &&
+   test_config branch.master.push for-john &&
+   git push down master:good &&
+   check_push_result up_repo $the_first_commit heads/master &&
+   check_push_result down_repo $the_commit heads/good
+'
+
 test_done


Felipe Contreras (8):
  t5516 (fetch-push): fix test restoration
  Add concept of 'publish' branch
  branch: add --set-publish-to option
  push: add --set-publish option
  branch: display publish branch
  sha1_name: cleanup interpret_branch_name()
  sha1_name: simplify track finding
  sha1_name: add support for @{publish} marks

 Documentation/config.txt |  7 
 Documentation/git-branch.txt | 11 +++
 Documentation/git-push.txt   |  9 +-
 Documentation/revisions.txt  |  4 +++
 branch.c | 44 +
 branch.h |  2 ++
 builtin/branch.c | 74 ++
 builtin/push.c   | 11 ++-
 remote.c | 34 
 remote.h |  4 +++
 sha1_name.c  | 62 ++--
 t/t1508-at-combinations.sh   |  5 +++
 t/t3200-branch.sh| 76 
 t/t5516-fetch-push.sh| 64 +
 t/t5534-push-publish.sh  | 70 
 t/t6040-tracking-info.sh |  5 +--
 transport.c  | 28 ++--
 transport.h  |  1 +
 18 files changed, 463 insertions(+), 48 deletions(-)
 create mode 100755 t/t5534-push-publish.sh

-- 
1.9.1+fc1

--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3 8/8] sha1_name: add support for @{publish} marks

2014-04-11 Thread Felipe Contreras
Signed-off-by: Felipe Contreras 
---
 Documentation/revisions.txt |  4 
 sha1_name.c | 49 -
 t/t1508-at-combinations.sh  |  5 +
 3 files changed, 40 insertions(+), 18 deletions(-)

diff --git a/Documentation/revisions.txt b/Documentation/revisions.txt
index 5a286d0..fd01cb4 100644
--- a/Documentation/revisions.txt
+++ b/Documentation/revisions.txt
@@ -96,6 +96,10 @@ some output processing may assume ref names in UTF-8.
   refers to the branch that the branch specified by branchname is set to build 
on
   top of.  A missing branchname defaults to the current one.
 
+'@\{publish\}', e.g. 'master@\{publish\}', '@\{p\}'::
+  The suffix '@\{publish\}' to a branchname refers to the remote branch to
+  push to. A missing branchname defaults to the current one.
+
 '{caret}', e.g. 'HEAD{caret}, v1.5.1{caret}0'::
   A suffix '{caret}' to a revision parameter means the first parent of
   that commit object.  '{caret}' means the th parent (i.e.
diff --git a/sha1_name.c b/sha1_name.c
index aa3f3e0..a36852d 100644
--- a/sha1_name.c
+++ b/sha1_name.c
@@ -415,9 +415,9 @@ static int ambiguous_path(const char *path, int len)
return slash;
 }
 
-static inline int upstream_mark(const char *string, int len)
+static inline int tracking_mark(const char *string, int len)
 {
-   const char *suffix[] = { "upstream", "u" };
+   const char *suffix[] = { "upstream", "u", "publish", "p" };
int i;
 
for (i = 0; i < ARRAY_SIZE(suffix); i++) {
@@ -475,7 +475,7 @@ static int get_sha1_basic(const char *str, int len, 
unsigned char *sha1)
nth_prior = 1;
continue;
}
-   if (!upstream_mark(str + at + 2, len - at - 3)) 
{
+   if (!tracking_mark(str + at + 2, len - at - 3)) 
{
reflog_len = (len-1) - (at+2);
len = at;
}
@@ -1057,10 +1057,11 @@ static void set_shortened_ref(struct strbuf *buf, const 
char *ref)
free(s);
 }
 
-static const char *get_upstream_branch(const char *name_buf, int len)
+static const char *get_tracking_branch(const char *name_buf, int len, char 
type)
 {
char *name = xstrndup(name_buf, len);
struct branch *branch = branch_get(*name ? name : NULL);
+   char *tracking = NULL;
 
/*
 * Upstream can be NULL only if branch refers to HEAD and HEAD
@@ -1068,23 +1069,35 @@ static const char *get_upstream_branch(const char 
*name_buf, int len)
 */
if (!branch)
die(_("HEAD does not point to a branch"));
-   if (!branch->merge || !branch->merge[0]->dst) {
-   if (!ref_exists(branch->refname))
-   die(_("No such branch: '%s'"), name);
-   if (!branch->merge) {
-   die(_("No upstream configured for branch '%s'"),
-   branch->name);
+   switch (type) {
+   case 'u':
+   if (!branch->merge || !branch->merge[0]->dst) {
+   if (!ref_exists(branch->refname))
+   die(_("No such branch: '%s'"), name);
+   if (!branch->merge) {
+   die(_("No upstream configured for branch '%s'"),
+   branch->name);
+   }
+   die(
+   _("Upstream branch '%s' not stored as a 
remote-tracking branch"),
+   branch->merge[0]->src);
+   }
+   tracking = branch->merge[0]->dst;
+   break;
+   case 'p':
+   if (!branch->push.dst) {
+   die(_("No publish configured for branch '%s'"),
+   branch->name);
}
-   die(
-   _("Upstream branch '%s' not stored as a remote-tracking 
branch"),
-   branch->merge[0]->src);
+   tracking = branch->push.dst;
+   break;
}
free(name);
 
-   return branch->merge[0]->dst;
+   return tracking;
 }
 
-static int interpret_upstream_mark(const char *name, int namelen,
+static int interpret_tracking_mark(const char *name, int namelen,
   int at, struct strbuf *buf)
 {
int len;
@@ -1092,14 +1105,14 @@ static

[PATCH v3 7/8] sha1_name: simplify track finding

2014-04-11 Thread Felipe Contreras
It's more efficient to check for the braces first.

Signed-off-by: Felipe Contreras 
---
 sha1_name.c | 11 +++
 1 file changed, 7 insertions(+), 4 deletions(-)

diff --git a/sha1_name.c b/sha1_name.c
index 906f09d..aa3f3e0 100644
--- a/sha1_name.c
+++ b/sha1_name.c
@@ -417,7 +417,7 @@ static int ambiguous_path(const char *path, int len)
 
 static inline int upstream_mark(const char *string, int len)
 {
-   const char *suffix[] = { "@{upstream}", "@{u}" };
+   const char *suffix[] = { "upstream", "u" };
int i;
 
for (i = 0; i < ARRAY_SIZE(suffix); i++) {
@@ -475,7 +475,7 @@ static int get_sha1_basic(const char *str, int len, 
unsigned char *sha1)
nth_prior = 1;
continue;
}
-   if (!upstream_mark(str + at, len - at)) {
+   if (!upstream_mark(str + at + 2, len - at - 3)) 
{
reflog_len = (len-1) - (at+2);
len = at;
}
@@ -1089,7 +1089,10 @@ static int interpret_upstream_mark(const char *name, int 
namelen,
 {
int len;
 
-   len = upstream_mark(name + at, namelen - at);
+   if (name[at + 1] != '{' || name[namelen - 1] != '}')
+   return -1;
+
+   len = upstream_mark(name + at + 2, namelen - at - 3);
if (!len)
return -1;
 
@@ -1097,7 +1100,7 @@ static int interpret_upstream_mark(const char *name, int 
namelen,
return -1;
 
set_shortened_ref(buf, get_upstream_branch(name, at));
-   return len + at;
+   return len + at + 3;
 }
 
 /*
-- 
1.9.1+fc1

--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3 3/8] branch: add --set-publish-to option

2014-04-11 Thread Felipe Contreras
Signed-off-by: Felipe Contreras 
---
 Documentation/git-branch.txt | 11 +++
 branch.c | 44 +
 branch.h |  2 ++
 builtin/branch.c | 57 ++---
 t/t3200-branch.sh| 76 
 5 files changed, 185 insertions(+), 5 deletions(-)

diff --git a/Documentation/git-branch.txt b/Documentation/git-branch.txt
index 311b336..914fd62 100644
--- a/Documentation/git-branch.txt
+++ b/Documentation/git-branch.txt
@@ -14,7 +14,9 @@ SYNOPSIS
[(--merged | --no-merged | --contains) []] [...]
 'git branch' [--set-upstream | --track | --no-track] [-l] [-f]  
[]
 'git branch' (--set-upstream-to= | -u ) []
+'git branch' (--set-publish-to= | -p ) []
 'git branch' --unset-upstream []
+'git branch' --unset-publish []
 'git branch' (-m | -M) [] 
 'git branch' (-d | -D) [-r] ...
 'git branch' --edit-description []
@@ -191,6 +193,15 @@ start-point is either a local or remote-tracking branch.
Remove the upstream information for . If no branch
is specified it defaults to the current branch.
 
+-p ::
+--set-publish-to=::
+   Set up 's publish tracking information. If no
+is specified, then it defaults to the current branch.
+
+--unset-publish::
+   Remove the publish information for . If no branch
+   is specified it defaults to the current branch.
+
 --edit-description::
Open an editor and edit the text to explain what the branch is
for, to be used by various other commands (e.g. `request-pull`).
diff --git a/branch.c b/branch.c
index 723a36b..090b3d1 100644
--- a/branch.c
+++ b/branch.c
@@ -144,6 +144,50 @@ static int setup_tracking(const char *new_ref, const char 
*orig_ref,
return 0;
 }
 
+void install_branch_publish(const char *name, const char *remote, const char 
*remote_ref)
+{
+   struct strbuf key = STRBUF_INIT;
+
+   if (!remote && !strcmp(name, remote_ref + 11) &&
+   starts_with(remote_ref, "refs/heads")) {
+   warning(_("Not setting branch %s as its own publish branch."), 
name);
+   return;
+   }
+
+   strbuf_addf(&key, "branch.%s.pushremote", name);
+   git_config_set(key.buf, remote ? remote : ".");
+
+   strbuf_reset(&key);
+   strbuf_addf(&key, "branch.%s.push", name);
+   git_config_set(key.buf, remote_ref);
+
+   strbuf_release(&key);
+}
+
+int setup_publish(const char *name, const char *ref)
+{
+   struct tracking tracking;
+   const char *remote, *remote_ref;
+
+   memset(&tracking, 0, sizeof(tracking));
+   tracking.spec.dst = (char *)ref;
+   if (for_each_remote(find_tracked_branch, &tracking))
+   return 1;
+
+   if (tracking.matches > 1)
+   return error(_("Not tracking: ambiguous information for ref 
%s"),
+   ref);
+
+   remote = tracking.remote;
+   remote_ref = tracking.src ? tracking.src : ref;
+
+   install_branch_publish(name, remote, remote_ref);
+
+   free(tracking.src);
+
+   return 0;
+}
+
 struct branch_desc_cb {
const char *config_name;
const char *value;
diff --git a/branch.h b/branch.h
index 64173ab..c9b6aa9 100644
--- a/branch.h
+++ b/branch.h
@@ -51,5 +51,7 @@ extern void install_branch_config(int flag, const char 
*local, const char *origi
  * Read branch description
  */
 extern int read_branch_desc(struct strbuf *, const char *branch_name);
+extern int setup_publish(const char *name, const char *ref);
+extern void install_branch_publish(const char *name, const char *remote, const 
char *remote_ref);
 
 #endif
diff --git a/builtin/branch.c b/builtin/branch.c
index b4d7716..17773d7 100644
--- a/builtin/branch.c
+++ b/builtin/branch.c
@@ -793,8 +793,8 @@ int cmd_branch(int argc, const char **argv, const char 
*prefix)
int delete = 0, rename = 0, force_create = 0, list = 0;
int verbose = 0, abbrev = -1, detached = 0;
int reflog = 0, edit_description = 0;
-   int quiet = 0, unset_upstream = 0;
-   const char *new_upstream = NULL;
+   int quiet = 0, unset_upstream = 0, unset_publish = 0;
+   const char *new_upstream = NULL, *publish = NULL;
enum branch_track track;
int kinds = REF_LOCAL_BRANCH;
struct commit_list *with_commit = NULL;
@@ -809,7 +809,9 @@ int cmd_branch(int argc, const char **argv, const char 
*prefix)
OPT_SET_INT( 0, "set-upstream",  &track, N_("change upstream 
info"),
BRANCH_TRACK_OVERRIDE),
OPT_STRING('u', "set-upstream-to", &new_upstream, "upstream", 
"change the upstream info"),
+   OPT_S

[PATCH v3 6/8] sha1_name: cleanup interpret_branch_name()

2014-04-11 Thread Felipe Contreras
The 'upstream' variable doesn't hold an "upstream", but a branch, so
make it clearer.

Signed-off-by: Felipe Contreras 
---
 sha1_name.c | 24 
 1 file changed, 12 insertions(+), 12 deletions(-)

diff --git a/sha1_name.c b/sha1_name.c
index 6fca869..906f09d 100644
--- a/sha1_name.c
+++ b/sha1_name.c
@@ -1057,31 +1057,31 @@ static void set_shortened_ref(struct strbuf *buf, const 
char *ref)
free(s);
 }
 
-static const char *get_upstream_branch(const char *branch_buf, int len)
+static const char *get_upstream_branch(const char *name_buf, int len)
 {
-   char *branch = xstrndup(branch_buf, len);
-   struct branch *upstream = branch_get(*branch ? branch : NULL);
+   char *name = xstrndup(name_buf, len);
+   struct branch *branch = branch_get(*name ? name : NULL);
 
/*
 * Upstream can be NULL only if branch refers to HEAD and HEAD
 * points to something different than a branch.
 */
-   if (!upstream)
+   if (!branch)
die(_("HEAD does not point to a branch"));
-   if (!upstream->merge || !upstream->merge[0]->dst) {
-   if (!ref_exists(upstream->refname))
-   die(_("No such branch: '%s'"), branch);
-   if (!upstream->merge) {
+   if (!branch->merge || !branch->merge[0]->dst) {
+   if (!ref_exists(branch->refname))
+   die(_("No such branch: '%s'"), name);
+   if (!branch->merge) {
die(_("No upstream configured for branch '%s'"),
-   upstream->name);
+   branch->name);
}
die(
_("Upstream branch '%s' not stored as a remote-tracking 
branch"),
-   upstream->merge[0]->src);
+   branch->merge[0]->src);
}
-   free(branch);
+   free(name);
 
-   return upstream->merge[0]->dst;
+   return branch->merge[0]->dst;
 }
 
 static int interpret_upstream_mark(const char *name, int namelen,
-- 
1.9.1+fc1

--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3 5/8] branch: display publish branch

2014-04-11 Thread Felipe Contreras
It does it along the upstream branch, if any.

* publish ... [master, gh/publish: ahead 1] ...
  master  ... [master, gh/master] ...

Signed-off-by: Felipe Contreras 
---
 builtin/branch.c | 17 -
 t/t6040-tracking-info.sh |  5 +++--
 2 files changed, 19 insertions(+), 3 deletions(-)

diff --git a/builtin/branch.c b/builtin/branch.c
index 17773d7..e0a8d0a 100644
--- a/builtin/branch.c
+++ b/builtin/branch.c
@@ -42,6 +42,7 @@ static char branch_colors[][COLOR_MAXLEN] = {
GIT_COLOR_NORMAL,   /* LOCAL */
GIT_COLOR_GREEN,/* CURRENT */
GIT_COLOR_BLUE, /* UPSTREAM */
+   GIT_COLOR_YELLOW,   /* PUBLISH */
 };
 enum color_branch {
BRANCH_COLOR_RESET = 0,
@@ -49,7 +50,8 @@ enum color_branch {
BRANCH_COLOR_REMOTE = 2,
BRANCH_COLOR_LOCAL = 3,
BRANCH_COLOR_CURRENT = 4,
-   BRANCH_COLOR_UPSTREAM = 5
+   BRANCH_COLOR_UPSTREAM = 5,
+   BRANCH_COLOR_PUBLISH = 6
 };
 
 static enum merge_filter {
@@ -76,6 +78,8 @@ static int parse_branch_color_slot(const char *var, int ofs)
return BRANCH_COLOR_CURRENT;
if (!strcasecmp(var+ofs, "upstream"))
return BRANCH_COLOR_UPSTREAM;
+   if (!strcasecmp(var+ofs, "publish"))
+   return BRANCH_COLOR_PUBLISH;
return -1;
 }
 
@@ -448,6 +452,17 @@ static void fill_tracking_info(struct strbuf *stat, const 
char *branch_name,
else
strbuf_addstr(&fancy, ref);
}
+   if (branch->push.dst) {
+   ref = shorten_unambiguous_ref(branch->push.dst, 0);
+   if (fancy.len)
+   strbuf_addstr(&fancy, ", ");
+   if (want_color(branch_use_color))
+   strbuf_addf(&fancy, "%s%s%s",
+   branch_get_color(BRANCH_COLOR_PUBLISH),
+   ref, 
branch_get_color(BRANCH_COLOR_RESET));
+   else
+   strbuf_addstr(&fancy, ref);
+   }
 
if (upstream_is_gone) {
if (show_upstream_ref)
diff --git a/t/t6040-tracking-info.sh b/t/t6040-tracking-info.sh
index 7ac8fd0..8b9ef63 100755
--- a/t/t6040-tracking-info.sh
+++ b/t/t6040-tracking-info.sh
@@ -33,7 +33,8 @@ test_expect_success setup '
git checkout -b b5 --track brokenbase &&
advance g &&
git branch -d brokenbase &&
-   git checkout -b b6 origin
+   git checkout -b b6 origin &&
+   git branch --set-publish origin/master b6
) &&
git checkout -b follower --track master &&
advance h
@@ -64,7 +65,7 @@ b2 [origin/master: ahead 1, behind 1] d
 b3 [origin/master: behind 1] b
 b4 [origin/master: ahead 2] f
 b5 [brokenbase: gone] g
-b6 [origin/master] c
+b6 [origin/master, origin/master] c
 EOF
 
 test_expect_success 'branch -vv' '
-- 
1.9.1+fc1

--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: Our official home page and logo for the Git project

2014-04-11 Thread Felipe Contreras
Max Horn wrote:
> On 11.04.2014, at 17:21, Felipe Contreras  wrote:
> > Max Horn wrote:
> >> On 11.04.2014, at 15:29, Felipe Contreras  
> >> wrote:
> >>> Max Horn wrote:
> >>> 
> >>> You don't think red represent an oldness in Git? Whereas green
> >>> represents progress?
> >> 
> >> No, I don't think that.
> > 
> > Then you belong to the minority of Git users. Those of us that see
> > patches day and night, red is old, green is new.
> 
> Hasty generalization.

You don't know what a hasty generalization is. If you want me to explain it to
you, send me a personal e-mail, you are polluting the discussion enough as it
is.

> Come back when you have facts, as opposed to the illusion that you are the
> spokesperson of the (apparently silent) majority of Git users.

Facts:

1) A hunk that removed (-) is represented in red [1]
2) A hunk that added (+) is represented in green [1]
3) A file that is removed is represented in red [2]
4) A file that is added or modified is represented in green [2]
5) A test that fails is represented in red [3]
6) A test that succeeds is represented in green [3]
7) The current Git logo (accordo to some people) has "-" in red, "+" in green 
[4]

Given these facts, it's reasonable to assume that to the majority of Git users
red is old and bad, green is new and good.

[1] http://ubuntuone.com/0lxzuxY2b59OEdDK5EOvfi
[2] 
http://media.smashingmagazine.com/wp-content/uploads/2011/06/git1_4_git-status.gif
[3] http://felipec.org/git-tests.png
[4] https://plus.google.com/112500102483798323902/posts

-- 
Felipe Contreras
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2 0/9] Introduce publish tracking branch

2014-04-11 Thread Felipe Contreras
Matthieu Moy wrote:
> Felipe Contreras  writes:
> 
> > My patch series only affects push.default=simple, perhaps you have a
> > different configuration.
> 
> Good catch. I have push.default=upstream (essentially for compatibility
> with old Git versions, I'd prefer simple actually).
> 
> > Maybe we want the publish branch to override any push.default, so:
> 
> Not sure actually. If a user says "push.default=upstream", it seems
> weird to push to something other than upstream indeed. What's clear to
> me is that your patch in its current form clearly makes "simple" a much
> better default than "upstream" (good news, it it the default!).

As you said in another email; that's just the default. If the user explicitely
told Git to use certain branch (git push -p), Git should use that branch.

> That said, the advice given by "git status" is clearly wrong:
> 
> > >   $ git status
> > >   On branch master
> > >   Your branch is ahead of 'origin/new' by 4 commits.
> > > (use "git push" to publish your local commits)
> 
> It should say (use "git push origin new" to publish your local commits)
> with push.default=upstream and the current behavior of the patch.
> 
> Perhaps argumentless "git push" could warn when push.default=upstream
> and branch..publish is configured, I'm not sure.
> 
> Sorry, more questions and "I'm not sure" than actual suggestion :-(.

I believe in v3 of the patch series "git push" will actually do it correctly.

Cheers.

-- 
Felipe Contreras
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2 6/9] branch: display publish branch

2014-04-11 Thread Felipe Contreras
Junio C Hamano wrote:
> Jeff King  writes:
> 
> > For instance, it looks like your @{publish} requires config like:
> >
> >   [branch "master"]
> >   pushremote = foo
> >   push = refs/heads/bar
> >
> > to operate. Setting "pushremote" affects what "git push" does; it will
> > go to the "foo" remote.
> 
> OK, and the same thing would happen if branch.*.pushremote is not
> set for any branch, but remote.pushdefault is set to 'foo', right?
> 
> > But the branch.master.push setting does not do
> > anything to "git push".
> 
> I am not sure I understand this.  I thought that the desire behind
> the branch.*.push is to allow something like:
> 
>   ... other things in the config ...
>   [remote]
>   pushdefault = foo
>   [remote "foo"]
>   url = ...
>   push = +refs/heads/*:refs/remotes/satellite/*
> fetch = +refs/heads/*:refs/remotes/foo/*
>   [branch "master"]
>   ; pushremote = foo
>   push = refs/heads/bar
> 
> so that "git push" on 'master' will override the more generic "all
> local branches here will go to their remote-tracking hierarchy for
> this satellite" refspec.  And in that sense branch.master.push would
> do something to "git push".

In my patches the above doesn't work; branch.master.push doesn't do anything if
.pushremote isn't there.

I'm always thinking from the common user's point of view, and the common user
doesn't know what branch.master.push is, but he knows he did
`git branch -p foo/bar master` (or something like that), and
`git branch -v` would corroborate that.

So you would have something like this:

[remote "foo"]
url = ...
push = +refs/heads/*:refs/remotes/satellite/*
fetch = +refs/heads/*:refs/remotes/foo/*
[branch "master"]
pushremote = foo
push = refs/heads/bar

> I personally think that kind of override adds any more values than
> it causes confusion, so I think it is OK not to support such uses of
> branch.*.push at all.  A configuration without branch.master.push
> may cause "git push" on 'master' to update refs/heads/master at the
> remote,

How? If branch.master.push is not configured, then "git push" would push
'master' to refs/remotes/satellite/master on the remote.

-- 
Felipe Contreras
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


  1   2   3   4   5   6   7   8   9   10   >