[PATCH] fast-import: do not truncate exported marks file
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
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
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
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
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
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
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"
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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()
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
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()
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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()
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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()
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
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
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
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
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