Re: [PATCH v2 02/11] tests: at-combinations: check ref names directly
On Wed, May 8, 2013 at 12:55 AM, Junio C Hamano gits...@pobox.com wrote: Felipe Contreras felipe.contre...@gmail.com writes: Some committishes might point to the same commit, but through a different ref, that's why it's better to check directly for the ref, rather than the commit message. We can do that by calling rev-parse --symbolic-full-name, and to differentiate the old from the new behavior we add an extra argument to the check() helper. Signed-off-by: Ramkumar Ramachandra artag...@gmail.com Signed-off-by: Felipe Contreras felipe.contre...@gmail.com --- It is signed-off by Ram first but who is the author? You, or him? I am, but he sent the patch first. t/t1508-at-combinations.sh | 27 --- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/t/t1508-at-combinations.sh b/t/t1508-at-combinations.sh index 46e3f16..bd2d2fe 100755 --- a/t/t1508-at-combinations.sh +++ b/t/t1508-at-combinations.sh @@ -4,9 +4,14 @@ test_description='test various @{X} syntax combinations together' . ./test-lib.sh check() { -test_expect_${3:-success} $1 = $2 - echo '$2' expect - git log -1 --format=%s '$1' actual +test_expect_${4:-success} $1 = $3 + if [ '$2' == 'commit' ]; then + echo '$3' expect + git log -1 --format=%s '$1' actual + else + echo '$3' expect + git rev-parse --symbolic-full-name '$1' actual + fi Move the echo outside of if, and match the overall style. Right. -- 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 03/11] tests: at-combinations: improve nonsense()
On Wed, May 8, 2013 at 12:55 AM, Junio C Hamano gits...@pobox.com wrote: Felipe Contreras felipe.contre...@gmail.com writes: In some circumstances 'git log' might fail, but not because the @ parsing failed. For example: 'git rev-parse' might succeed and return a bad object, and then 'git log' would fail. The layer we want to test is revision parsing, so let's test that directly. Hmph, but git rev-parse Makefile would happily succeed if there happens to be Makefile in the directory. Are we expecting that they are always object names? If that is the case, perhaps git rev-parse --verify $1 would express the intention better. Probably, although the same would fail before this patch. -- 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: What's cooking in git.git (May 2013, #02; Mon, 6)
Felipe Contreras wrote: This series has cleanups and features that are good as they are. Ramkumar said he was going to resend his cleanup series, but he didn't. I'll try to gather all the patches and split them into cleanups, and features. Thanks for picking up the pieces. I was out of town these last few days. -- 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/2] completion: zsh wrapper cleanups
Hi, Nothing fancy, just some cleanups for the minimal zsh backup wrapper in bash's completion code. Felipe Contreras (2): completion: cleanup zsh wrapper completion: synchronize zsh wrapper contrib/completion/git-completion.bash | 22 +++--- 1 file changed, 7 insertions(+), 15 deletions(-) -- 1.8.3.rc1.553.gac13664 -- 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/2] completion: cleanup zsh wrapper
There's no need for a separate function; we can call 'emulate -k ksh func'. Signed-off-by: Felipe Contreras felipe.contre...@gmail.com --- contrib/completion/git-completion.bash | 18 +- 1 file changed, 5 insertions(+), 13 deletions(-) diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash index b97162f..84dbf19 100644 --- a/contrib/completion/git-completion.bash +++ b/contrib/completion/git-completion.bash @@ -2689,21 +2689,13 @@ if [[ -n ${ZSH_VERSION-} ]]; then compadd -Q -p ${2-} -f -- ${=1} _ret=0 } - __git_zsh_helper () - { - emulate -L ksh - local cur cword prev - cur=${words[CURRENT-1]} - prev=${words[CURRENT-2]} - let cword=CURRENT-1 - __${service}_main - } - _git () { - emulate -L zsh - local _ret=1 - __git_zsh_helper + 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 -S '' _ret=0 return _ret } -- 1.8.3.rc1.553.gac13664 -- 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/2] completion: synchronize zsh wrapper
So it's closer to the full zsh wrapper. Signed-off-by: Felipe Contreras felipe.contre...@gmail.com --- 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 84dbf19..b61f6c2 100644 --- a/contrib/completion/git-completion.bash +++ b/contrib/completion/git-completion.bash @@ -2663,7 +2663,7 @@ if [[ -n ${ZSH_VERSION-} ]]; then --*=*|*.) ;; *) c=$c ;; esac - array[$#array+1]=$c + array+=($c) done compset -P '*[=:]' compadd -Q -S '' -p ${2-} -a -- array _ret=0 @@ -2696,7 +2696,7 @@ if [[ -n ${ZSH_VERSION-} ]]; then prev=${words[CURRENT-1]} let cword=CURRENT-1 emulate ksh -c __${service}_main - let _ret _default -S '' _ret=0 + let _ret _default _ret=0 return _ret } -- 1.8.3.rc1.553.gac13664 -- 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 10/11] sha1_name: reorganize get_sha1_basic()
Felipe Contreras wrote: --- sha1_name.c | 30 +++--- 1 file changed, 19 insertions(+), 11 deletions(-) How has this changed since my eyeballing of the previous version? An inter-diff would be nice: having spent a significant amount of time looking at this area, I can confirm that the patch is Correct. -- 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 10/11] sha1_name: reorganize get_sha1_basic()
On Wed, May 8, 2013 at 2:39 AM, Ramkumar Ramachandra artag...@gmail.com wrote: Felipe Contreras wrote: --- sha1_name.c | 30 +++--- 1 file changed, 19 insertions(+), 11 deletions(-) How has this changed since my eyeballing of the previous version? An inter-diff would be nice: having spent a significant amount of time looking at this area, I can confirm that the patch is Correct. You mean this compared to v4? It hasn't changed. -- 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: trouble on windows network share
Here's one more data point. It suggests that the problem is due to either Cygwin or possibly Git 1.7.9. My Ubuntu box is actually a VM, hosted by my windows box in VMWare Player. So, I tried using the VMWare shared folder feature, to mount the Windows U: drive (which is physically on the WD NAS box) as /mnt/hgfs/Host-U on Ubuntu. Then, I tried linux on the Ubuntu box, fully expecting it to fail as it trampolined through Windows connection to the NAS box). But, it worked fine. So, at this point, it became likely that the problem is tied to the different version of Git that I have on the two machines: - On Ubuntu, git version 1.7.10.4 - On Windows, Cygwin's git version 1.7.9 (which appears to be the latest version for Cygwin). So, I installed Git on Windows from http://git-scm.com/download/win. Git version 1.8.1.msysgit.1 Triumph: Git on windows works with this git but, on the same file and repo, fails with Cygwin git. So, either something relevant changed in Git 1.7.10, or (more likely) this is a Cygwin issue. Jason, are you also using Cygwin git? Are you also using a WD NAS? David -Original Message- From: Pyeron, Jason J CTR (US) [mailto:jason.j.pyeron@mail.mil] Sent: Monday, May 06, 2013 4:11 PM To: Thomas Rast; David Goldfarb Cc: git@vger.kernel.org Subject: RE: trouble on windows network share -Original Message- From: Thomas Rast Sent: Monday, May 06, 2013 5:42 AM David Goldfarb d...@degel.com writes: Git works correctly under Linux (Ubuntu 12.04; git 1.7.9.5). I've attached the strace outputs. (Note: for reasons that are probably irrelevant, I needed to run the commands sudo'd. Shout back if this is an issue). Under Windows 7, Cygwin git 1.7.9, commit fails: U:\foogit commit -m added foo2 error: unable to find 0b89efdeef245ed6a0a7eacc5c578629a141f856 fatal: 0b89efdeef245ed6a0a7eacc5c578629a141f856 is not a valid object For what it's worth, note that the file does exist. U:\fools -l .git/objects/0b total 1024 -rwxrw-r-- 1 74 May 5 01:15 89efdeef245ed6a0a7eacc5c578629a141f856 (I'm not sure why the permissions are trashed. Seems to be a Cygwin thing, or maybe my Cygwin config. The ?? also appears on local files, and I believe also with files on the old Buffalo drive, so I don't think it is relevant to the problem). Just in case, here's the same dir, as seen from the Ubuntu VM: deg@ubuntu:/mnt/users/foo$ ls -l .git/objects/0b total 64 -rwxr-xr-x 0 root root 74 May 5 01:15 89efdeef245ed6a0a7eacc5c578629a141f856 Again, note that there is some user permissions lossage here. I don't know enough about Linux mount or CIFS, and apparently did the mount in a way that everything seems to appear to be stuck owned by root. (same problem I hinted at above). Hope this is not relevant to the problem. Here's how the same directory looks, when I'm ssh'd into the NAS box itself: CentralPark:/shares/Users/foo# ls -l .git/objects/0b total 64 -rwxrw-r-- 1 deg share 74 May 5 01:15 89efdeef245ed6a0a7eacc5c578629a141f856 In any event, the symptoms don't seem to be a permissions problem, so all this extra info is probably just a red herring, I hope. Hrm. What about what Jeff already asked of the OP (and AFAICS never got a reply)? If referring to me, then yes but it was too big for the list. } If it's a race condition between the write and the subsequent read in } the same process, then it would be solved by looking at the object } later. Does git cat-file -p 6838761d549cf76033d2e9faf5954e62839eb25d } work, or is the object forever inaccessible? In your case: git cat-file -p 0b89efdeef245ed6a0a7eacc5c578629a141f856 -- 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
Minor correction to Git book
I'm just learning Git so I don't yet know how to submit this as a patch, but I'm reading the Git Book to get myself started and I think there is a mistake on the page at: http://git-scm.com/book/en/Git-Basics-Recording-Changes-to-the-Repository It says: For another example, if you stage the benchmarks.rb file and then edit it, you can use git diff to see the changes in the file that are staged and the changes that are unstaged: I believe this should say git status rather than git diff. -- Robin This email is confidential and intended solely for the use of the individual to whom it is addressed. If you are not the intended recipient, be advised that you have received this email in error and that any use, disclosure, copying or distribution or any action taken or omitted to be taken in reliance on it is strictly prohibited. If you have received this email in error please contact the sender. Any views or opinions presented in this email are solely those of the author and do not necessarily represent those of Altran. Although this email and any attachments are believed to be free of any virus or other defect, no responsibility is accepted by Altran or any of its associated companies for any loss or damage arising in any way from the receipt or use thereof. Altran UK Ltd: Company Number: 3302507, registered in England and Wales Registered Address: 22 St. Lawrence Street, Bath, BA1 1AN VAT Registered in Great Britain: 682635707 -- 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 00/11] sha1_name: improvements
Junio C Hamano wrote: Will queue. Thanks. Nit: you might want to add my s-o-b on patches 73027d and b018e8 queued in pu. -- 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: Minor correction to Git book
On Wed, May 08, 2013 at 11:24:56AM +0100, Robin Messer wrote: I'm just learning Git so I don't yet know how to submit this as a patch, but I'm reading the Git Book to get myself started and I think there is a mistake on the page at: http://git-scm.com/book/en/Git-Basics-Recording-Changes-to-the-Repository It says: For another example, if you stage the benchmarks.rb file and then edit it, you can use git diff to see the changes in the file that are staged and the changes that are unstaged: I believe this should say git status rather than git diff. I think the text is correct as it stands. git status shows you that there are changes that are staged and unstaged, git diff (and git diff --cached) shows you what those changes are. -- 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: Minor correction to Git book
I think the text is correct as it stands. git status shows you that there are changes that are staged and unstaged, git diff (and git diff --cached) shows you what those changes are. Thanks, but the command line which follows that text does actually use git status to show which files (staged and unstaged) have changes. The text I quoted is introducing that command. Then the next example shows you how to use git diff to see what the actual unstaged changes to those files are. If this is not the appropriate place to report such things, please point me at the correct one. Thanks, Robin. This email is confidential and intended solely for the use of the individual to whom it is addressed. If you are not the intended recipient, be advised that you have received this email in error and that any use, disclosure, copying or distribution or any action taken or omitted to be taken in reliance on it is strictly prohibited. If you have received this email in error please contact the sender. Any views or opinions presented in this email are solely those of the author and do not necessarily represent those of Altran. Although this email and any attachments are believed to be free of any virus or other defect, no responsibility is accepted by Altran or any of its associated companies for any loss or damage arising in any way from the receipt or use thereof. Altran UK Ltd: Company Number: 3302507, registered in England and Wales Registered Address: 22 St. Lawrence Street, Bath, BA1 1AN VAT Registered in Great Britain: 682635707 -- 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: Minor correction to Git book
On Wed, May 08, 2013 at 12:01:00PM +0100, Robin Messer wrote: I think the text is correct as it stands. git status shows you that there are changes that are staged and unstaged, git diff (and git diff --cached) shows you what those changes are. Thanks, but the command line which follows that text does actually use git status to show which files (staged and unstaged) have changes. The text I quoted is introducing that command. Then the next example shows you how to use git diff to see what the actual unstaged changes to those files are. Ah, OK. I read your email without looking at the context. If this is not the appropriate place to report such things, please point me at the correct one. The ProGit book is maintained at https://github.com/progit/progit -- 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 v7 00/10] interactive git clean
Significant updates since patch v6 series: * Refactor on patch 4/10: split `list_and_choose` into 3 functions, to make it easy to read. * Mark no public functions as static for patch 1-10. * If set 'pager.clean' to true (i.e. isatty(1) is false), die instead of do cleaning. * New action: flags. The user can update flags for git-clean, such as -x/-d/-X/-ff. * Alway show interactive menu, even there are no files to clean. Because the use can update flags for git-clean. Usage: When the command enters the interactive mode, it shows the files and directories to be cleaned, and goes into its interactive command loop. The command loop shows the list of subcommands available, and gives a prompt What now . In general, when the prompt ends with a single '', you can pick only one of the choices given and type return, like this: *** Commands *** 1: clean 2: edit by patterns3: edit by numbers 4: rm -i 5: flags: none 6: quit7: help What now 2 You also could say `c` or `clean` above as long as the choice is unique. The main command loop has 7 subcommands. clean:: Start cleaning files and directories, and then quit. edit by patterns:: This shows the files and directories to be deleted and issues an Input ignore patterns prompt. You can input a space-seperated patterns to exclude files and directories from deletion. E.g. *.c *.h will excludes files end with .c and .h from deletion. When you are satisfied with the filtered result, press ENTER (empty) back to the main menu. edit by numbers:: This shows the files and directories to be deleted and issues an Select items to delete prompt. When the prompt ends with double '' like this, you can make more than one selection, concatenated with whitespace or comma. Also you can say ranges. E.g. 2-5 7,9 to choose 2,3,4,5,7,9 from the list. If the second number in a range is omitted, all remaining patches are taken. E.g. 7- to choose 7,8,9 from the list. You can say '*' to choose everything. Also when you are satisfied with the filtered result, press ENTER (empty) back to the main menu. rm -i:: This will show a rm -i style cleaning, that you must confirm one by one in order to delete items. This action is not as efficient as the above two actions. flags:: This lets you change the flags for git-clean, such as -x/-X/-d/-ff, and refresh the cleaning candidates list automatically. quit:: This lets you quit without do cleaning. help:: Show brief usage of interactive git-clean. Jiang Xin (10): Add support for -i/--interactive to git-clean Show items of interactive git-clean in columns Add colors to interactive git-clean git-clean: use a git-add-interactive compatible UI git-clean: interactive cleaning by select numbers git-clean: rm -i style interactive cleaning git-clean: update document for interactive git-clean git-clean refactor: save some options in clean_flags git-clean refactor: wrap in scan_clean_candidates git-clean: change clean flags in interactive mode Documentation/config.txt| 4 + Documentation/git-clean.txt | 76 +++- builtin/clean.c | 972 3 files changed, 981 insertions(+), 71 deletions(-) -- 1.8.3.rc1.341.g1c24ab7 -- 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 v7 01/10] Add support for -i/--interactive to git-clean
Show what would be done and the user must confirm before actually cleaning. In the confirmation dialog, the user has three choices: * y/yes: Start to do cleaning. * n/no: Nothing will be deleted. * e/edit: Exclude items from deletion using ignore patterns. When the user chooses the edit mode, the user can input space- separated patterns (the same syntax as gitignore), and each clean candidate that matches with one of the patterns will be excluded from cleaning. When the user feels it's OK, presses ENTER and back to the confirmation dialog. Signed-off-by: Jiang Xin worldhello@gmail.com Suggested-by: Junio C Hamano gits...@pobox.com Spelling-checked-by: Eric Sunshine sunsh...@sunshineco.com Comments-by: Matthieu Moy matthieu@imag.fr Suggested-by: Eric Sunshine sunsh...@sunshineco.com --- Documentation/git-clean.txt | 15 +++- builtin/clean.c | 198 +++- 2 files changed, 192 insertions(+), 21 deletions(-) diff --git a/Documentation/git-clean.txt b/Documentation/git-clean.txt index bdc3a..f5572 100644 --- a/Documentation/git-clean.txt +++ b/Documentation/git-clean.txt @@ -8,7 +8,7 @@ git-clean - Remove untracked files from the working tree SYNOPSIS [verse] -'git clean' [-d] [-f] [-n] [-q] [-e pattern] [-x | -X] [--] path... +'git clean' [-d] [-f] [-i] [-n] [-q] [-e pattern] [-x | -X] [--] path... DESCRIPTION --- @@ -34,7 +34,18 @@ OPTIONS -f:: --force:: If the Git configuration variable clean.requireForce is not set - to false, 'git clean' will refuse to run unless given -f or -n. + to false, 'git clean' will refuse to run unless given -f, -n or + -i. + +-i:: +--interactive:: + Show what would be done and the user must confirm before actually + cleaning. In the confirmation dialog, the user can choose to abort + the cleaning, or enter into an edit mode. In the edit mode, the + user can input space-separated patterns (the same syntax as + gitignore), and each clean candidate that matches with one of the + patterns will be excluded from cleaning. When the user feels it's + OK, presses ENTER and back to the confirmation dialog. -n:: --dry-run:: diff --git a/builtin/clean.c b/builtin/clean.c index 04e39..49aab 100644 --- a/builtin/clean.c +++ b/builtin/clean.c @@ -15,9 +15,12 @@ #include quote.h static int force = -1; /* unset */ +static int interactive; +static struct string_list del_list = STRING_LIST_INIT_DUP; +static const char **the_prefix; static const char *const builtin_clean_usage[] = { - N_(git clean [-d] [-f] [-n] [-q] [-e pattern] [-x | -X] [--] paths...), + N_(git clean [-d] [-f] [-i] [-n] [-q] [-e pattern] [-x | -X] [--] paths...), NULL }; @@ -142,6 +145,139 @@ static int remove_dirs(struct strbuf *path, const char *prefix, int force_flag, return ret; } +static void edit_by_patterns_cmd() +{ + struct dir_struct dir; + struct strbuf confirm = STRBUF_INIT; + struct strbuf buf = STRBUF_INIT; + struct strbuf **ignore_list; + struct string_list_item *item; + struct exclude_list *el; + const char *qname; + int changed = -1, i; + + while (1) { + /* dels list may become empty when we run string_list_remove_empty_items later */ + if (!del_list.nr) { + printf_ln(_(No more files to clean, exiting.)); + break; + } + + if (changed) { + putchar('\n'); + + /* Display dels in Would remove ... format */ + for_each_string_list_item(item, del_list) { + qname = quote_path_relative(item-string, -1, buf, *the_prefix); + printf(_(msg_would_remove), qname); + } + putchar('\n'); + } + + printf(_(Input ignore patterns )); + if (strbuf_getline(confirm, stdin, '\n') != EOF) { + strbuf_trim(confirm); + } else { + putchar('\n'); + break; + } + + /* Quit edit mode */ + if (!confirm.len) + break; + + memset(dir, 0, sizeof(dir)); + el = add_exclude_list(dir, EXC_CMDL, manual exclude); + ignore_list = strbuf_split_max(confirm, ' ', 0); + + for (i = 0; ignore_list[i]; i++) { + strbuf_trim(ignore_list[i]); + if (!ignore_list[i]-len) + continue; + + add_exclude(ignore_list[i]-buf, , 0, el, -(i+1)); + } + + changed = 0; + for_each_string_list_item(item, del_list) { + int dtype = DT_UNKNOWN; +
[PATCH v7 02/10] Show items of interactive git-clean in columns
When there are lots of items to be cleaned, it is hard to see them all in one screen. Show them in columns instead of in one column will solve this problem. Since no longer show items to be cleaned using the Would remove ... format (only plain filenames) in interactive mode, we add instructions and warnings as header before them. Signed-off-by: Jiang Xin worldhello@gmail.com Comments-by: Matthieu Moy matthieu@imag.fr --- Documentation/config.txt | 4 builtin/clean.c | 58 +--- 2 files changed, 44 insertions(+), 18 deletions(-) diff --git a/Documentation/config.txt b/Documentation/config.txt index 6e53f..98bfa 100644 --- a/Documentation/config.txt +++ b/Documentation/config.txt @@ -955,6 +955,10 @@ column.branch:: Specify whether to output branch listing in `git branch` in columns. See `column.ui` for details. +column.clean:: + Specify whether to output cleaning files in `git clean -i` in columns. + See `column.ui` for details. + column.status:: Specify whether to output untracked files in `git status` in columns. See `column.ui` for details. diff --git a/builtin/clean.c b/builtin/clean.c index 49aab..38ed0 100644 --- a/builtin/clean.c +++ b/builtin/clean.c @@ -13,11 +13,13 @@ #include refs.h #include string-list.h #include quote.h +#include column.h static int force = -1; /* unset */ static int interactive; static struct string_list del_list = STRING_LIST_INIT_DUP; static const char **the_prefix; +static unsigned int colopts; static const char *const builtin_clean_usage[] = { N_(git clean [-d] [-f] [-i] [-n] [-q] [-e pattern] [-x | -X] [--] paths...), @@ -32,8 +34,13 @@ static const char *msg_warn_remove_failed = N_(failed to remove %s); static int git_clean_config(const char *var, const char *value, void *cb) { - if (!strcmp(var, clean.requireforce)) + if (!prefixcmp(var, column.)) + return git_column_config(var, value, clean, colopts); + + if (!strcmp(var, clean.requireforce)) { force = !git_config_bool(var, value); + return 0; + } return git_default_config(var, value, cb); } @@ -145,6 +152,33 @@ static int remove_dirs(struct strbuf *path, const char *prefix, int force_flag, return ret; } +static void pretty_print_dels() +{ + struct string_list list = STRING_LIST_INIT_DUP; + struct string_list_item *item; + struct strbuf buf = STRBUF_INIT; + const char *qname; + struct column_options copts; + + for_each_string_list_item(item, del_list) { + qname = quote_path_relative(item-string, -1, buf, *the_prefix); + string_list_append(list, qname); + } + + /* +* always enable column display, we only consult column.* +* about layout strategy and stuff +*/ + colopts = (colopts ~COL_ENABLE_MASK) | COL_ENABLED; + memset(copts, 0, sizeof(copts)); + copts.indent = ; + copts.padding = 2; + print_columns(list, colopts, copts); + putchar('\n'); + strbuf_release(buf); + string_list_clear(list, 0); +} + static void edit_by_patterns_cmd() { struct dir_struct dir; @@ -153,7 +187,6 @@ static void edit_by_patterns_cmd() struct strbuf **ignore_list; struct string_list_item *item; struct exclude_list *el; - const char *qname; int changed = -1, i; while (1) { @@ -166,12 +199,8 @@ static void edit_by_patterns_cmd() if (changed) { putchar('\n'); - /* Display dels in Would remove ... format */ - for_each_string_list_item(item, del_list) { - qname = quote_path_relative(item-string, -1, buf, *the_prefix); - printf(_(msg_would_remove), qname); - } - putchar('\n'); + /* Display dels in columns */ + pretty_print_dels(); } printf(_(Input ignore patterns )); @@ -228,23 +257,17 @@ static void edit_by_patterns_cmd() static void interactive_main_loop() { struct strbuf confirm = STRBUF_INIT; - struct strbuf buf = STRBUF_INIT; - struct string_list_item *item; - const char *qname; /* dels list may become empty after return back from edit mode */ while (del_list.nr) { + putchar('\n'); printf_ln(Q_(Would remove the following item:, Would remove the following items:, del_list.nr)); putchar('\n'); - /* Display dels in Would remove ... format */ - for_each_string_list_item(item, del_list) { - qname = quote_path_relative(item-string, -1, buf,
[PATCH v7 03/10] Add colors to interactive git-clean
Show header, help, error messages, and prompt in colors for interactive git-clean. Re-use config variables for other git commands, such as git-add--interactive and git-stash: * color.interactive: When set to always, always use colors for interactive prompts and displays. When false (or never), never. When set to true or auto, use colors only when the output is to the terminal. * color.interactive.slot: Use customized color for interactive git-clean output (like git add --interactive). slot may be prompt, header, help or error. Signed-off-by: Jiang Xin worldhello@gmail.com Comments-by: Matthieu Moy matthieu@imag.fr --- builtin/clean.c | 78 - 1 file changed, 77 insertions(+), 1 deletion(-) diff --git a/builtin/clean.c b/builtin/clean.c index 38ed0..9b029 100644 --- a/builtin/clean.c +++ b/builtin/clean.c @@ -14,6 +14,7 @@ #include string-list.h #include quote.h #include column.h +#include color.h static int force = -1; /* unset */ static int interactive; @@ -32,16 +33,81 @@ static const char *msg_skip_git_dir = N_(Skipping repository %s\n); static const char *msg_would_skip_git_dir = N_(Would skip repository %s\n); static const char *msg_warn_remove_failed = N_(failed to remove %s); +static int clean_use_color = -1; +static char clean_colors[][COLOR_MAXLEN] = { + GIT_COLOR_RESET, + GIT_COLOR_NORMAL, /* PLAIN */ + GIT_COLOR_BOLD_BLUE,/* PROMPT */ + GIT_COLOR_BOLD, /* HEADER */ + GIT_COLOR_BOLD_RED, /* HELP */ + GIT_COLOR_BOLD_RED, /* ERROR */ +}; +enum color_clean { + CLEAN_COLOR_RESET = 0, + CLEAN_COLOR_PLAIN = 1, + CLEAN_COLOR_PROMPT = 2, + CLEAN_COLOR_HEADER = 3, + CLEAN_COLOR_HELP = 4, + CLEAN_COLOR_ERROR = 5, +}; + +static int parse_clean_color_slot(const char *var, int ofs) +{ + if (!strcasecmp(var+ofs, reset)) + return CLEAN_COLOR_RESET; + if (!strcasecmp(var+ofs, plain)) + return CLEAN_COLOR_PLAIN; + if (!strcasecmp(var+ofs, prompt)) + return CLEAN_COLOR_PROMPT; + if (!strcasecmp(var+ofs, header)) + return CLEAN_COLOR_HEADER; + if (!strcasecmp(var+ofs, help)) + return CLEAN_COLOR_HELP; + if (!strcasecmp(var+ofs, error)) + return CLEAN_COLOR_ERROR; + return -1; +} + static int git_clean_config(const char *var, const char *value, void *cb) { if (!prefixcmp(var, column.)) return git_column_config(var, value, clean, colopts); + /* honors the color.interactive* config variables which also + applied in git-add--interactive and git-stash */ + if (!strcmp(var, color.interactive)) { + clean_use_color = git_config_colorbool(var, value); + return 0; + } + if (!prefixcmp(var, color.interactive.)) { + int slot = parse_clean_color_slot(var, 18); + if (slot 0) + return 0; + if (!value) + return config_error_nonbool(var); + color_parse(value, var, clean_colors[slot]); + return 0; + } + if (!strcmp(var, clean.requireforce)) { force = !git_config_bool(var, value); return 0; } - return git_default_config(var, value, cb); + + /* inspect the color.ui config variable and others */ + return git_color_default_config(var, value, cb); +} + +static const char *clean_get_color(enum color_clean ix) +{ + if (want_color(clean_use_color)) + return clean_colors[ix]; + return ; +} + +static void clean_print_color(enum color_clean ix) +{ + printf(%s, clean_get_color(ix)); } static int exclude_cb(const struct option *opt, const char *arg, int unset) @@ -192,7 +258,9 @@ static void edit_by_patterns_cmd() while (1) { /* dels list may become empty when we run string_list_remove_empty_items later */ if (!del_list.nr) { + clean_print_color(CLEAN_COLOR_ERROR); printf_ln(_(No more files to clean, exiting.)); + clean_print_color(CLEAN_COLOR_RESET); break; } @@ -203,7 +271,9 @@ static void edit_by_patterns_cmd() pretty_print_dels(); } + clean_print_color(CLEAN_COLOR_PROMPT); printf(_(Input ignore patterns )); + clean_print_color(CLEAN_COLOR_RESET); if (strbuf_getline(confirm, stdin, '\n') != EOF) { strbuf_trim(confirm); } else { @@ -243,7 +313,9 @@ static void edit_by_patterns_cmd() if (changed) { string_list_remove_empty_items(del_list, 0); } else { +
[PATCH v7 04/10] git-clean: use a git-add-interactive compatible UI
Rewrite menu using a new method `list_and_choose`, which is borrowed from `git-add--interactive.perl`. We can reused this method later for more actions. Please NOTE: * Method `list_and_choose` return an array of integers, and * it is up to you to free the allocated memory of the array. * The array ends with EOF. * If user pressed CTRL-D (i.e. EOF), no selection returned. Signed-off-by: Jiang Xin worldhello@gmail.com --- builtin/clean.c | 469 +++- 1 file changed, 428 insertions(+), 41 deletions(-) diff --git a/builtin/clean.c b/builtin/clean.c index 9b029..10f3 100644 --- a/builtin/clean.c +++ b/builtin/clean.c @@ -51,6 +51,36 @@ enum color_clean { CLEAN_COLOR_ERROR = 5, }; +#define MENU_OPTS_SINGLETON01 +#define MENU_OPTS_IMMEDIATE02 +#define MENU_OPTS_LIST_ONLY04 + +struct menu_opts { + const char *header; + const char *prompt; + int flag; +}; + +#define MENU_RETURN_NO_LOOP10 + +struct menu_item { + char hotkey; + char *title; + int selected; + int (*fn)(); +}; + +enum menu_stuff_type { + MENU_STUFF_TYPE_STRING_LIST = 1, + MENU_STUFF_TYPE_MENU_ITEM +}; + +struct menu_stuff { + enum menu_stuff_type type; + int nr; + void *stuff; +}; + static int parse_clean_color_slot(const char *var, int ofs) { if (!strcasecmp(var+ofs, reset)) @@ -240,12 +270,345 @@ static void pretty_print_dels() copts.indent = ; copts.padding = 2; print_columns(list, colopts, copts); - putchar('\n'); strbuf_release(buf); string_list_clear(list, 0); } -static void edit_by_patterns_cmd() +static void pretty_print_menus(struct string_list *menu_list) +{ + unsigned int local_colopts = 0; + struct column_options copts; + + local_colopts = COL_ENABLED | COL_ROW; + memset(copts, 0, sizeof(copts)); + copts.indent = ; + copts.padding = 2; + print_columns(menu_list, local_colopts, copts); +} + +static void prompt_help_cmd(int singleton) +{ + clean_print_color(CLEAN_COLOR_HELP); + printf_ln(singleton ? + _(Prompt help:\n + 1 - select a numbered item\n + foo- select item based on unique prefix\n + - (empty) select nothing) : + _(Prompt help:\n + 1 - select a single item\n + 3-5- select a range of items\n + 2-3,6-9- select multiple ranges\n + foo- select item based on unique prefix\n + -... - unselect specified items\n + * - choose all items\n + - (empty) finish selecting)); + clean_print_color(CLEAN_COLOR_RESET); +} + +/* + * display menu stuff with number prefix and hotkey highlight + */ +static void print_highlight_menu_stuff(struct menu_stuff *stuff, int **chosen) +{ + static struct string_list menu_list = STRING_LIST_INIT_DUP; + struct strbuf menu = STRBUF_INIT; + int i; + + /* highlight hotkey in menu */ + if (MENU_STUFF_TYPE_MENU_ITEM == stuff-type) { + struct menu_item *item; + + item = (struct menu_item *)stuff-stuff; + for (i = 0; i stuff-nr; i++, item++) { + char *p; + int highlighted = 0; + + p = item-title; + if ((*chosen)[i] 0) + (*chosen)[i] = item-selected ? 1 : 0; + strbuf_addf(menu, %s%2d: , (*chosen)[i] ? * : , i+1); + for (; *p; p++) { + if (!highlighted *p == item-hotkey) { + strbuf_addstr(menu, clean_get_color(CLEAN_COLOR_PROMPT)); + strbuf_addch(menu, *p); + strbuf_addstr(menu, clean_get_color(CLEAN_COLOR_RESET)); + highlighted = 1; + } else { + strbuf_addch(menu, *p); + } + } + string_list_append(menu_list, menu.buf); + strbuf_reset(menu); + } + } else if (MENU_STUFF_TYPE_STRING_LIST == stuff-type) { + struct string_list_item *item; + struct strbuf buf = STRBUF_INIT; + i = 0; + + for_each_string_list_item(item, (struct string_list *)stuff-stuff) { + const char *qname; + + if ((*chosen)[i] 0) + (*chosen)[i] = 0; + qname = quote_path_relative(item-string, -1, buf,
[PATCH v7 05/10] git-clean: interactive cleaning by select numbers
Draw a multiple choice menu using `list_and_choose` to select items to be deleted by numbers. User can input: * 1,5-7 : select 1,5,6,7 items to be deleted * * : select all items to be deleted * -*: unselect all, nothing will be deleted *: (empty) finish selecting, and return back to main menu Signed-off-by: Jiang Xin worldhello@gmail.com --- builtin/clean.c | 39 +++ 1 file changed, 39 insertions(+) diff --git a/builtin/clean.c b/builtin/clean.c index 10f3..75e37 100644 --- a/builtin/clean.c +++ b/builtin/clean.c @@ -684,6 +684,43 @@ static int edit_by_patterns_cmd() return 0; } +static int edit_by_numbers_cmd() +{ + struct menu_opts menu_opts; + struct menu_stuff menu_stuff; + struct string_list_item *items; + int *chosen; + int i, j; + + menu_opts.header = NULL; + menu_opts.prompt = Select items to delete; + menu_opts.flag = 0; + + menu_stuff.type = MENU_STUFF_TYPE_STRING_LIST; + menu_stuff.stuff = del_list; + menu_stuff.nr = del_list.nr; + + chosen = list_and_choose(menu_opts, menu_stuff); + items = del_list.items; + for(i = 0, j = 0; i del_list.nr; i++) { + if (i chosen[j]) { + *(items[i].string) = '\0'; + } else if (i == chosen[j]) { + /* delete selected item */ + j++; + continue; + } else { + /* end of chosen (EOF), won't delete */ + *(items[i].string) = '\0'; + } + } + + string_list_remove_empty_items(del_list, 0); + + free(chosen); + return 0; +} + static int quit_cmd() { string_list_clear(del_list, 0); @@ -697,6 +734,7 @@ static int help_cmd(int x) printf_ln(_( clean- start cleaning\n edit by patterns - exclude items from deletion\n + edit by numbers - select items to be deleted by numbers\n quit - stop cleaning\n help - this screen\n ?- help for prompt selection @@ -714,6 +752,7 @@ static void interactive_main_loop() struct menu_item menus[] = { {'c', clean, 0, clean_cmd}, {'p', edit by patterns, 0, edit_by_patterns_cmd}, + {'n', edit by numbers,0, edit_by_numbers_cmd}, {'q', quit, 0, quit_cmd}, {'h', help, 0, help_cmd}, }; -- 1.8.3.rc1.341.g1c24ab7 -- 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 v7 06/10] git-clean: rm -i style interactive cleaning
Add a rm -i style interactive cleaning method. User must confirm one by one before starting to delete. Signed-off-by: Jiang Xin worldhello@gmail.com --- builtin/clean.c | 36 1 file changed, 36 insertions(+) diff --git a/builtin/clean.c b/builtin/clean.c index 75e37..5bb36 100644 --- a/builtin/clean.c +++ b/builtin/clean.c @@ -721,6 +721,40 @@ static int edit_by_numbers_cmd() return 0; } +static int rm_i_cmd() +{ + struct strbuf confirm = STRBUF_INIT; + struct strbuf buf = STRBUF_INIT; + struct string_list_item *item; + const char *qname; + int changed = 0, eof = 0; + + for_each_string_list_item(item, del_list) { + /* Ctrl-D should stop removing files */ + if (!eof) { + qname = quote_path_relative(item-string, -1, buf, *the_prefix); + printf(_(remove %s ? ), qname); + if (strbuf_getline(confirm, stdin, '\n') != EOF) { + strbuf_trim(confirm); + } else { + putchar('\n'); + eof = 1; + } + } + if (!confirm.len || !strncasecmp(confirm.buf, no, confirm.len)) { + *item-string = '\0'; + changed++; + } + } + + if (changed) + string_list_remove_empty_items(del_list, 0); + + strbuf_release(buf); + strbuf_release(confirm); + return MENU_RETURN_NO_LOOP; +} + static int quit_cmd() { string_list_clear(del_list, 0); @@ -735,6 +769,7 @@ static int help_cmd(int x) clean- start cleaning\n edit by patterns - exclude items from deletion\n edit by numbers - select items to be deleted by numbers\n + rm -i- delete items one by one, like \rm -i\\n quit - stop cleaning\n help - this screen\n ?- help for prompt selection @@ -753,6 +788,7 @@ static void interactive_main_loop() {'c', clean, 0, clean_cmd}, {'p', edit by patterns, 0, edit_by_patterns_cmd}, {'n', edit by numbers,0, edit_by_numbers_cmd}, + {'i', rm -i, 0, rm_i_cmd}, {'q', quit, 0, quit_cmd}, {'h', help, 0, help_cmd}, }; -- 1.8.3.rc1.341.g1c24ab7 -- 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 v7 07/10] git-clean: update document for interactive git-clean
Signed-off-by: Jiang Xin worldhello@gmail.com --- Documentation/git-clean.txt | 70 - 1 file changed, 63 insertions(+), 7 deletions(-) diff --git a/Documentation/git-clean.txt b/Documentation/git-clean.txt index f5572..47e8e 100644 --- a/Documentation/git-clean.txt +++ b/Documentation/git-clean.txt @@ -39,13 +39,8 @@ OPTIONS -i:: --interactive:: - Show what would be done and the user must confirm before actually - cleaning. In the confirmation dialog, the user can choose to abort - the cleaning, or enter into an edit mode. In the edit mode, the - user can input space-separated patterns (the same syntax as - gitignore), and each clean candidate that matches with one of the - patterns will be excluded from cleaning. When the user feels it's - OK, presses ENTER and back to the confirmation dialog. + Show what would be done and clean files interactively. See + ``Interactive mode'' for details. -n:: --dry-run:: @@ -74,6 +69,67 @@ OPTIONS Remove only files ignored by Git. This may be useful to rebuild everything from scratch, but keep manually created files. +Interactive mode + +When the command enters the interactive mode, it shows the +files and directories to be cleaned, and goes into its +interactive command loop. + +The command loop shows the list of subcommands available, and +gives a prompt What now . In general, when the prompt ends +with a single '', you can pick only one of the choices given +and type return, like this: + + +*** Commands *** + 1: clean 2: edit by patterns 3: edit by numbers + 4. rm -i 5. quit 6. help +What now 2 + + +You also could say `c` or `clean` above as long as the choice is unique. + +The main command loop has 6 subcommands. + +clean:: + + Start cleaning files and directories, and then quit. + +edit by patterns:: + + This shows the files and directories to be deleted and issues an + Input ignore patterns prompt. You can input a space-seperated + patterns to exclude files and directories from deletion. + E.g. *.c *.h will excludes files end with .c and .h from + deletion. When you are satisfied with the filtered result, press + ENTER (empty) back to the main menu. + +edit by numbers:: + + This shows the files and directories to be deleted and issues an + Select items to delete prompt. When the prompt ends with double + '' like this, you can make more than one selection, concatenated + with whitespace or comma. Also you can say ranges. E.g. 2-5 7,9 + to choose 2,3,4,5,7,9 from the list. If the second number in a + range is omitted, all remaining patches are taken. E.g. 7- to + choose 7,8,9 from the list. You can say '*' to choose everything. + Also when you are satisfied with the filtered result, press ENTER + (empty) back to the main menu. + +rm -i:: + + This will show a rm -i style cleaning, that you must confirm one + by one in order to delete items. This action is not as efficient + as the above two actions. + +quit:: + + This lets you quit without do cleaning. + +help:: + + Show brief usage of interactive git-clean. + SEE ALSO linkgit:gitignore[5] -- 1.8.3.rc1.341.g1c24ab7 -- 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 v7 08/10] git-clean refactor: save some options in clean_flags
Save some options in variable clean_flags, such as -ff (force 1), -x (ignored), -X (ignored_only), and -d (remove_directories). We may change clean_flags later in the interactive git-clean. Signed-off-by: Jiang Xin worldhello@gmail.com --- builtin/clean.c | 46 +++--- 1 file changed, 31 insertions(+), 15 deletions(-) diff --git a/builtin/clean.c b/builtin/clean.c index 5bb36..d46f3 100644 --- a/builtin/clean.c +++ b/builtin/clean.c @@ -16,7 +16,13 @@ #include column.h #include color.h +#define CLEAN_OPTS_SHOW_IGNORED01 +#define CLEAN_OPTS_IGNORED_ONLY02 +#define CLEAN_OPTS_REMOVE_DIRECTORIES 04 +#define CLEAN_OPTS_REMOVE_NESTED_GIT 010 + static int force = -1; /* unset */ +static int clean_flags = 0; static int interactive; static struct string_list del_list = STRING_LIST_INIT_DUP; static const char **the_prefix; @@ -843,7 +849,6 @@ int cmd_clean(int argc, const char **argv, const char *prefix) int i, res; int dry_run = 0, remove_directories = 0, quiet = 0, ignored = 0; int ignored_only = 0, config_set = 0, errors = 0, gone = 1; - int rm_flags = REMOVE_DIR_KEEP_NESTED_GIT; struct strbuf directory = STRBUF_INIT; struct dir_struct dir; static const char **pathspec; @@ -879,13 +884,6 @@ int cmd_clean(int argc, const char **argv, const char *prefix) argc = parse_options(argc, argv, *the_prefix, options, builtin_clean_usage, 0); - memset(dir, 0, sizeof(dir)); - if (ignored_only) - dir.flags |= DIR_SHOW_IGNORED; - - if (ignored ignored_only) - die(_(-x and -X cannot be used together)); - if (interactive) { if (!isatty(0) || !isatty(1)) die(_(interactive clean can not run without a valid tty; @@ -899,15 +897,29 @@ int cmd_clean(int argc, const char **argv, const char *prefix) refusing to clean)); } + if (read_cache() 0) + die(_(index file corrupt)); + if (force 1) - rm_flags = 0; + clean_flags |= CLEAN_OPTS_REMOVE_NESTED_GIT; + if (ignored) + clean_flags |= CLEAN_OPTS_SHOW_IGNORED; + if (ignored_only) + clean_flags |= CLEAN_OPTS_IGNORED_ONLY; + if (remove_directories) + clean_flags |= CLEAN_OPTS_REMOVE_DIRECTORIES; - dir.flags |= DIR_SHOW_OTHER_DIRECTORIES; + memset(dir, 0, sizeof(dir)); + if (clean_flags CLEAN_OPTS_IGNORED_ONLY) + dir.flags |= DIR_SHOW_IGNORED; - if (read_cache() 0) - die(_(index file corrupt)); + if (clean_flags CLEAN_OPTS_IGNORED_ONLY + clean_flags CLEAN_OPTS_SHOW_IGNORED) + die(_(-x and -X cannot be used together)); + + dir.flags |= DIR_SHOW_OTHER_DIRECTORIES; - if (!ignored) + if (!(clean_flags CLEAN_OPTS_SHOW_IGNORED)) setup_standard_excludes(dir); el = add_exclude_list(dir, EXC_CMDL, --exclude option); @@ -961,7 +973,8 @@ int cmd_clean(int argc, const char **argv, const char *prefix) } if (S_ISDIR(st.st_mode)) { - if (remove_directories || (matches == MATCHED_EXACTLY)) + if ((clean_flags CLEAN_OPTS_REMOVE_DIRECTORIES) || + (matches == MATCHED_EXACTLY)) string_list_append(del_list, ent-name); } else { if (pathspec !matches) @@ -981,7 +994,10 @@ int cmd_clean(int argc, const char **argv, const char *prefix) if (S_ISDIR(st.st_mode)) { strbuf_addstr(directory, item-string); - if (remove_dirs(directory, *the_prefix, rm_flags, dry_run, quiet, gone)) + if (remove_dirs(directory, *the_prefix, + clean_flags CLEAN_OPTS_REMOVE_NESTED_GIT ? + 0 : REMOVE_DIR_KEEP_NESTED_GIT, + dry_run, quiet, gone)) errors++; if (gone !quiet) { qname = quote_path_relative(directory.buf, directory.len, buf, *the_prefix); -- 1.8.3.rc1.341.g1c24ab7 -- 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 v7 09/10] git-clean refactor: wrap in scan_clean_candidates
Add new function `scan_clean_candidates`, which determines the del_list (i.e. the cleaning candidates). This function will be reused later in the interactive git-clean, so we can change flags of git-clean and refresh the del_list. Signed-off-by: Jiang Xin worldhello@gmail.com --- builtin/clean.c | 169 ++-- 1 file changed, 92 insertions(+), 77 deletions(-) diff --git a/builtin/clean.c b/builtin/clean.c index d46f3..0d8561 100644 --- a/builtin/clean.c +++ b/builtin/clean.c @@ -254,6 +254,95 @@ static int remove_dirs(struct strbuf *path, const char *prefix, int force_flag, return ret; } +static void scan_clean_candidates(const char **pathspec, struct string_list exclude_list) +{ + struct dir_struct dir; + struct exclude_list *el; + char *seen = NULL; + const char **pathspec_p = pathspec; + int pathspec_nr = 0; + int i; + + while (pathspec_p *(pathspec_p++)) + pathspec_nr++; + + memset(dir, 0, sizeof(dir)); + if (clean_flags CLEAN_OPTS_IGNORED_ONLY) + dir.flags |= DIR_SHOW_IGNORED; + + if (clean_flags CLEAN_OPTS_IGNORED_ONLY + clean_flags CLEAN_OPTS_SHOW_IGNORED) + die(_(-x and -X cannot be used together)); + + dir.flags |= DIR_SHOW_OTHER_DIRECTORIES; + + if (!(clean_flags CLEAN_OPTS_SHOW_IGNORED)) + setup_standard_excludes(dir); + + el = add_exclude_list(dir, EXC_CMDL, --exclude option); + for (i = 0; i exclude_list.nr; i++) + add_exclude(exclude_list.items[i].string, , 0, el, -(i+1)); + + fill_directory(dir, pathspec); + + if (pathspec) + seen = xmalloc(pathspec_nr 0 ? pathspec_nr : 1); + + string_list_clear(del_list, 0); + + for (i = 0; i dir.nr; i++) { + struct dir_entry *ent = dir.entries[i]; + int len, pos; + int matches = 0; + struct cache_entry *ce; + struct stat st; + + /* +* Remove the '/' at the end that directory +* walking adds for directory entries. +*/ + len = ent-len; + if (len ent-name[len-1] == '/') + len--; + pos = cache_name_pos(ent-name, len); + if (0 = pos) + continue; /* exact match */ + pos = -pos - 1; + if (pos active_nr) { + ce = active_cache[pos]; + if (ce_namelen(ce) == len + !memcmp(ce-name, ent-name, len)) + continue; /* Yup, this one exists unmerged */ + } + + /* +* we might have removed this as part of earlier +* recursive directory removal, so lstat() here could +* fail with ENOENT. +*/ + if (lstat(ent-name, st)) + continue; + + if (pathspec) { + memset(seen, 0, pathspec_nr 0 ? pathspec_nr : 1); + matches = match_pathspec(pathspec, ent-name, len, +0, seen); + } + + if (S_ISDIR(st.st_mode)) { + if ((clean_flags CLEAN_OPTS_REMOVE_DIRECTORIES) || + (matches == MATCHED_EXACTLY)) + string_list_append(del_list, ent-name); + } else { + if (pathspec !matches) + continue; + string_list_append(del_list, ent-name); + } + } + + free(seen); +} + static void pretty_print_dels() { struct string_list list = STRING_LIST_INIT_DUP; @@ -846,18 +935,15 @@ static void interactive_main_loop() int cmd_clean(int argc, const char **argv, const char *prefix) { - int i, res; + int res; int dry_run = 0, remove_directories = 0, quiet = 0, ignored = 0; int ignored_only = 0, config_set = 0, errors = 0, gone = 1; struct strbuf directory = STRBUF_INIT; - struct dir_struct dir; static const char **pathspec; struct strbuf buf = STRBUF_INIT; - struct string_list exclude_list = STRING_LIST_INIT_NODUP; - struct exclude_list *el; struct string_list_item *item; + struct string_list exclude_list = STRING_LIST_INIT_NODUP; const char *qname; - char *seen = NULL; struct option options[] = { OPT__QUIET(quiet, N_(do not print names of files removed)), OPT__DRY_RUN(dry_run, N_(dry run)), @@ -909,79 +995,9 @@ int cmd_clean(int argc, const char **argv, const char *prefix) if (remove_directories) clean_flags |= CLEAN_OPTS_REMOVE_DIRECTORIES; - memset(dir,
[PATCH v7 10/10] git-clean: change clean flags in interactive mode
Add new action in the interactive mode, so that the user can change git-clean flags, such as -x/-X/-d/-ff, and refresh the cleaning candidates list. Signed-off-by: Jiang Xin worldhello@gmail.com --- Documentation/git-clean.txt | 11 +++-- builtin/clean.c | 117 +--- 2 files changed, 108 insertions(+), 20 deletions(-) diff --git a/Documentation/git-clean.txt b/Documentation/git-clean.txt index 47e8e..c7885 100644 --- a/Documentation/git-clean.txt +++ b/Documentation/git-clean.txt @@ -82,14 +82,14 @@ and type return, like this: *** Commands *** - 1: clean 2: edit by patterns 3: edit by numbers - 4. rm -i 5. quit 6. help + 1: clean 2: edit by patterns3: edit by numbers 4: rm -i + 5: flags: none 6: quit7: help What now 2 You also could say `c` or `clean` above as long as the choice is unique. -The main command loop has 6 subcommands. +The main command loop has 7 subcommands. clean:: @@ -122,6 +122,11 @@ rm -i:: by one in order to delete items. This action is not as efficient as the above two actions. +flags:: + + This lets you change the flags for git-clean, such as -x/-X/-d/-ff, + and refresh the cleaning candidates list automatically. + quit:: This lets you quit without do cleaning. diff --git a/builtin/clean.c b/builtin/clean.c index 0d8561..b2941 100644 --- a/builtin/clean.c +++ b/builtin/clean.c @@ -850,6 +850,66 @@ static int rm_i_cmd() return MENU_RETURN_NO_LOOP; } +static int flags_cmd() +{ + struct menu_opts menu_opts; + struct menu_stuff menu_stuff; + struct menu_item menus[] = { + {'d', (-d) remove directories, + clean_flags CLEAN_OPTS_REMOVE_DIRECTORIES,NULL}, + {'x', (-x) show ignored, + clean_flags CLEAN_OPTS_SHOW_IGNORED, NULL}, + {'X', (-X) ignored only, + clean_flags CLEAN_OPTS_IGNORED_ONLY, NULL}, + {'f', (-ff) remove nested.git, + clean_flags CLEAN_OPTS_REMOVE_NESTED_GIT, NULL}, + }; + int new_flags = 0; + int *chosen; + int i; + + menu_opts.header = NULL; + menu_opts.prompt = Change flags; + menu_opts.flag = 0; + + menu_stuff.type = MENU_STUFF_TYPE_MENU_ITEM; + menu_stuff.stuff = menus; + menu_stuff.nr = sizeof(menus) / sizeof(struct menu_item); + + chosen = list_and_choose(menu_opts, menu_stuff); + + for (i = 0; chosen[i] != EOF; i++) { + switch (chosen[i]) { + case 0: + new_flags |= CLEAN_OPTS_REMOVE_DIRECTORIES; + break; + case 1: + new_flags |= CLEAN_OPTS_SHOW_IGNORED; + break; + case 2: + new_flags |= CLEAN_OPTS_IGNORED_ONLY; + break; + case 3: + new_flags |= CLEAN_OPTS_REMOVE_NESTED_GIT; + break; + default: + break; + } + } + + if (new_flags CLEAN_OPTS_IGNORED_ONLY + new_flags CLEAN_OPTS_SHOW_IGNORED) { + clean_print_color(CLEAN_COLOR_ERROR); + printf_ln(_(-x and -X cannot be used together)); + clean_print_color(CLEAN_COLOR_RESET); + } else { + clean_flags = new_flags; + } + + free(chosen); + return 0; +} + static int quit_cmd() { string_list_clear(del_list, 0); @@ -865,6 +925,7 @@ static int help_cmd(int x) edit by patterns - exclude items from deletion\n edit by numbers - select items to be deleted by numbers\n rm -i- delete items one by one, like \rm -i\\n + flags- change git-clean flags and update the cleaning candidates\n quit - stop cleaning\n help - this screen\n ?- help for prompt selection @@ -873,10 +934,13 @@ static int help_cmd(int x) return 0; } -static void interactive_main_loop() +static void interactive_main_loop(const char **pathspec, struct string_list exclude_list) { + int cached_clean_flags = clean_flags; + char flags_title[20]; + /* dels list may become empty after return back from edit mode */ - while (del_list.nr) { + while (1) { struct menu_opts menu_opts; struct menu_stuff menu_stuff; struct menu_item menus[] = { @@ -884,11 +948,24 @@ static void interactive_main_loop() {'p', edit by patterns, 0, edit_by_patterns_cmd},
`git prune` doc or implementation defect, or user misunderstanding
The `git prune` documentation says: This runs git fsck --unreachable using all the refs available in refs/, optionally with additional set of objects specified on the command line, and prunes all unpacked objects unreachable from any of these head objects from the object database. In addition, it prunes the unpacked objects that are also found in packs by running git prune-packed. Note that unreachable, packed objects will remain. If this is not desired, see git-repack(1). My interpretation of that is that `git prune` will not prune packed objects by default. The following behavior seems inconsistent with that interpretation. [git@438587-beefcake01 panama.git]$ git prune -n | wc -l 9210 [git@438587-beefcake01 panama.git]$ git fsck --unreachable | wc -l 9468 [git@438587-beefcake01 panama.git]$ git gc --no-prune Counting objects: 531223, done. Delta compression using up to 24 threads. Compressing objects: 100% (109848/109848), done. Writing objects: 100% (531223/531223), done. Total 531223 (delta 405288), reused 530894 (delta 404961) [git@438587-beefcake01 panama.git]$ git prune -n | wc -l 9468 [git@438587-beefcake01 panama.git]$ git fsck --unreachable | wc -l 9468 It looks like `git prune -n` is telling me that it would prune the objects that I just packed. What am I misunderstanding? -- Matt McClure http://matthewlmcclure.com http://www.mapmyfitness.com/profile/matthewlmcclure -- 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: 3 way merge during git p4 rebase is attempting to reapply past commits
git p4 rebase and git p4 submit don't work on a bare repo (at least it didn't for me) This is weird since there is a --bare option for git p4 clone, but then you can't do git p4 submit's on that bare repo back up to perforce? I got an error stating: git p4 rebase Performing incremental import into refs/remotes/p4/master git branch Depot paths: //depot/path.to/folder/ No changes to import! fatal: This operation must be run in a work tree Some files in your working directory are modified and different than what is in your index. You can use git update-index filename to bring the index up-to-date or stash away all your changes with git stash. And I got this error for git p4 submit stating Perforce checkout for depot path //depot/path.to/folder/ located at /home/user1/path/to/perforce.folder/ Synchronizing p4 checkout... ... - file(s) up-to-date. fatal: Not a git repository: '.' Command failed: ['git', 'rev-list', '--no-merges', 'remotes/p4/master..master'] http://stackoverflow.com/questions/15512357/how-to-run-git-p4-submit-on-a-bare-repo (The workaround described seemed particularly convoluted.) My only (simple) workaround for that is doing the git checkout -f and git clean -f before and after doing git p4 rebase and git p4 submit ( http://stackoverflow.com/questions/15512700/replace-working-copy-of-git-repo-with-actual-contents-of-repo-in-git ) I've encountered so many errors over time that I can't trust to leave the operation scheduled, because some problem like this might crop up again. On Wed, May 8, 2013 at 1:35 AM, Luke Diamand l...@diamand.org wrote: On 08/05/13 00:12, Christopher Yee Mon wrote: Hello, I have a setup where I have a remote non-bare repo cloned from a perforce workspace. It is used as a remote repo that people clone into their own user repos, make commits to, then push back into the remote repo. Why is your p4 clone non-bare? I thought pushing into a non-bare repo tended to cause problems? Then I periodically run the following commands in a script to push those changes back to perforce. % man cron :-) git checkout -f git clean -f git p4 rebase --import-labels git p4 submit -M --export-labels git checkout -f git clean -f Sometimes, always after commits from one user's machine specifically, I get the following error below when pushing back to perforce at the remote repo. It seems to happen randomly, or at least intermittently, since I often can't discern any major error during git committing to the remote repo that precipitates this error. It does happen pretty reliably when I get a file conflict that I resolve and fix during committing though. Performing incremental import into refs/remotes/p4/master git branch Depot paths: //depot/sub/folder/ No changes to import! Rebasing the current branch onto remotes/p4/master First, rewinding head to replay your work on top of it... Applying: A commit that has already been made previously Applying: A second commit that has already been made in a previous commit Using index info to reconstruct a base tree... stdin:15: space before tab in indent. a line of text stdin:24: space before tab in indent. another line of text stdin:25: space before tab in indent. a third line of text stdin:33: trailing whitespace. a forth line of text stdin:71: trailing whitespace. warning: squelched 1 whitespace error warning: 6 lines add whitespace errors. Falling back to patching base and 3-way merge... Auto-merging file from second CONFLICT (content): Merge conflict in a/file/in/the/second/pre-existing/commit/file.php Auto-merging a/file/in/the/second/pre-existing/commit/file.php Failed to merge in the changes. Patch failed at 0002 A second commit that has already been made in a previous commit When you have resolved this problem run git rebase --continue. If you would prefer to skip this patch, instead run git rebase --skip. To check out the original branch and stop rebasing run git rebase --abort. Traceback (most recent call last): File /usr/lib/git-core/git-p4, line 3373, inmodule main() File /usr/lib/git-core/git-p4, line 3367, in main if not cmd.run(args): File /usr/lib/git-core/git-p4, line 3150, in run return self.rebase() File /usr/lib/git-core/git-p4, line 3167, in rebase system(git rebase %s % upstream) File /usr/lib/git-core/git-p4, line 183, in system raise CalledProcessError(retcode, cmd) subprocess.CalledProcessError: Command 'git rebase remotes/p4/master' returned non-zero exit status 1 The patch is usually one that is already in the remote git repo and in perforce. At that point I have to run git rebase --skip, to skip the patch, then rerun the commands in the script again. Sometimes it's multiple patches that cause this problem and I have to run git rebase --skip repeatedly. When I check the working copy of the remote repo, I don't see any
Re: `git prune` doc or implementation defect, or user misunderstanding
Am 5/8/2013 16:19, schrieb Matt McClure: My interpretation of that is that `git prune` will not prune packed objects by default. The following behavior seems inconsistent with that interpretation. [git@438587-beefcake01 panama.git]$ git prune -n | wc -l 9210 You have 9210 unreachable, loose objects. [git@438587-beefcake01 panama.git]$ git fsck --unreachable | wc -l 9468 You have 9468 unreachable objects in total. [git@438587-beefcake01 panama.git]$ git gc --no-prune Counting objects: 531223, done. Delta compression using up to 24 threads. Compressing objects: 100% (109848/109848), done. Writing objects: 100% (531223/531223), done. Total 531223 (delta 405288), reused 530894 (delta 404961) Only reachable objects go into the new pack. Unreachable objects that were in the pack before, are evicted and are now loose. [git@438587-beefcake01 panama.git]$ git prune -n | wc -l 9468 [git@438587-beefcake01 panama.git]$ git fsck --unreachable | wc -l 9468 Now all 9468 unreachable objects are loose and eligible for being pruned. It looks like `git prune -n` is telling me that it would prune the objects that I just packed. What am I misunderstanding? git gc moves unreachable objects that were packed before to the loose object store, from where they can be pruned. -- Hannes -- 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: Problems with Windows, Was: What's cooking in git.git (May 2013, #01; Fri, 3)
On 2013-05-08 02.30, Mark Levedahl wrote: On 05/07/2013 10:27 AM, Torsten Bögershausen wrote: On 2013-05-04 01.14, Junio C Hamano wrote: Cygwin portability; both were reviewed by Jonathan, and the tip one seems to want a bit further explanation. Needs positive report from Cygwin 1.7 users who have been on 1.7 to make sure it does not regress for them. I was trying to verify that cygwin 1.7 is still Ok, but got puzzled. Running the test suite under cygwin doesn't seem to work any more (?): Scenario 1: The PC is running alone, and goes into the screen saver. Pressing CTRL-ALT-DEL didn't get any effect. Scenario 2: The PC didn't react any more, when the test suite was run in background. In 3 or 4 cases the PC needed to be reboot hardly. Using the commits before and after this change makes the test suite hang as well at some point, then it hangs somewhere at TC 3000--4000. Scenario 4: The I disabled the screensaver, upgdated cygwin, and went back to an older commit: The latest run from commit 52d63e70, April 28, hangs in TC 5500, ok 26 clone shallow object count. I can see 2 times git.exe pull --depth 4 ..A Scenario 5: The run of today 1.8.3-rc1, hangs in t5510, some git.exe are running fetch. (or pull) It seems as if some process/exes are not terminated in the way it should be. I will try on a different machine, comments are wellcome /Torsten I have run into very similar problems trying to test these patches, so I declined to reply thinking someone else might have better or at least explicable results. I am able to build git on cygwin 1.7 using the proposed patches, it seems to work, but I've run into strange problems such as the main git repo becoming corrupted, no idea how or why. Mark I tried 1.8.3-rc1 on a different PC, and it seems to have the same hanging. So I will do some bisecting on master, and try to find out more. -- 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 v7 00/10] interactive git clean
On Wed, May 8, 2013 at 7:38 AM, Jiang Xin worldhello@gmail.com wrote: When the command enters the interactive mode, it shows the files and directories to be cleaned, and goes into its interactive command loop. Your current implementation only allows excluding items from the list of files to delete. If you accidentally exclude some file which you actually want in the deletion list, there is no way to re-add it. Would it make sense to change the behavior so that it lists all files but stars those which are to be deleted. This is similar to how the edit by numbers mode operates, but would apply to the deletion list printed for the top-level menu as well. For example: Will remove starred items: file1 *file2 *file3 *file4 file5 file6 *** Commands *** ... What now clean Removing file2 Removing file3 Removing file4 The command loop shows the list of subcommands available, and gives a prompt What now . In general, when the prompt ends with a single '', you can pick only one of the choices given and type return, like this: *** Commands *** 1: clean 2: edit by patterns3: edit by numbers 4: rm -i 5: flags: none 6: quit7: help What now 2 You also could say `c` or `clean` above as long as the choice is unique. It is not obvious by reading the menu that edit by patterns can be abbreviated as 'p', and edit by numbers by 'n'. If you change the names a bit, then the abbreviations become more obvious. For instance, one possibility: 2. filter by pattern 3. select by number 5. toggle flags: none Also, the abbreviation 'i' for rm -i is not obvious. edit by patterns:: This shows the files and directories to be deleted and issues an Input ignore patterns prompt. You can input a space-seperated patterns to exclude files and directories from deletion. E.g. *.c *.h will excludes files end with .c and .h from deletion. When you are satisfied with the filtered result, press ENTER (empty) back to the main menu. edit by numbers:: This shows the files and directories to be deleted and issues an Select items to delete prompt. When the prompt ends with double '' like this, you can make more than one selection, concatenated with whitespace or comma. Also you can say ranges. E.g. 2-5 7,9 to choose 2,3,4,5,7,9 from the list. If the second number in a range is omitted, all remaining patches are taken. E.g. 7- to choose 7,8,9 from the list. You can say '*' to choose everything. Also when you are satisfied with the filtered result, press ENTER (empty) back to the main menu. It seems odd that edit by patterns _excludes_ files from deletion, but edit by patterns _includes_ them in the deletion list. These opposing behaviors force the user to invert his mode of thought when editing by patterns vs. numbers. While playing with edit by numbers, I repeatedly found myself incorrectly inputting numbers of items I wanted to exclude rather than those I wanted to keep in the list, since my brain had not made the 180 degree flip from edit by patterns. More generally, there are cases when it is more convenient to filter the list by exclusion, and other cases when inclusion is more convenient. For example, in a list of 20 files, I may want to delete 18 but keep 2. In this case, it typically is easier to specify the two I want to keep. On the other hand, if I want to delete 2 files but keep 18, it may be easier to specify the two I want to delete. Would it makes sense to support pattern negation (via '!' perhaps) in order to make this possible? One thing not mentioned here is that edit by numbers (as with git-add-interactive) also accepts input foo to match item foo in the list. This suggests that it might make sense to accept patterns also, so that *oo can match foo. This, together with negation and the idea mentioned above of always listing all files and only deleting starred ones, would allow you to combine edit by patterns and edit by numbers into a single mode of operation. rm -i:: This will show a rm -i style cleaning, that you must confirm one by one in order to delete items. This action is not as efficient as the above two actions. The name rm -i is rather Unixy, and Windows users might not understand it, nor people who don't use rm's -i option. Other potentially better names might be: ask, ask each, confirm, confirm each, prompt, or prompt each. Functionally, the current implementation of this mode makes it an oddball. edit by patterns and edit by numbers both return to the top-level menu, allowing the user to invoke clean or quit (or some other option), but rm -i always finishes by running clean unconditionally. This is strangely inconsistent. Shouldn't it also return to the top-level menu to give the user an opportunity to review the final selection before invoking clean or quit? flags:: This lets you change the flags for git-clean,
Re: [PATCH v7 00/10] interactive git clean
On Wed, May 8, 2013 at 11:15 AM, Eric Sunshine sunsh...@sunshineco.com wrote: On Wed, May 8, 2013 at 7:38 AM, Jiang Xin worldhello@gmail.com wrote: *** Commands *** 1: clean 2: edit by patterns3: edit by numbers 4: rm -i 5: flags: none 6: quit7: help What now 2 You also could say `c` or `clean` above as long as the choice is unique. It is not obvious by reading the menu that edit by patterns can be abbreviated as 'p', and edit by numbers by 'n'. If you change the names a bit, then the abbreviations become more obvious. For instance, one possibility: 2. filter by pattern 3. select by number 5. toggle flags: none By more obvious, I meant that the initial letter of each option is now unique across the entire menu: 2. [f]ilter by pattern 3. [s]elect by number 4. [t]oggle flags: none -- 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 v7 00/10] interactive git clean
Eric Sunshine sunsh...@sunshineco.com writes: On Wed, May 8, 2013 at 7:38 AM, Jiang Xin worldhello@gmail.com wrote: When the command enters the interactive mode, it shows the files and directories to be cleaned, and goes into its interactive command loop. Your current implementation only allows excluding items from the list of files to delete. If you accidentally exclude some file which you actually want in the deletion list, there is no way to re-add it. If you accidentally dropped items from the list, is it such a big deal? I would imagine, if I were in that situation, that I would simply continue and concentrate on making sure the remaining list does not include anything I want to keep, clean them and then run the command again, at which point the list of untracked paths in the list will be much smaller. We cannot make the same argument against the approach to first present a list and _remove_ items that should not be dropped. That is a genuine improvement, without which you cannot do a similar incremental removal, whose first invocation removes only a subset (but still a subset with no precious files you need to keep) of files to allow the list subsequent invocations presents to *shrink*. Cleaning all unneeded files inside a single interactive session should *never* be the goal---that will lead to an over-engineered design (e.g. switching clean -x flags in the middle? why?). I think Jiang's latest series is already way over-engineered, and I suspect your suggestion leads it more into that direction. -- 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
Avoiding broken Gitweb links and deleted objects
On Wed, May 8, 2013 at 12:05 PM, Matt McClure matthewlmccl...@gmail.com wrote: On Wed, May 8, 2013 at 10:41 AM, Johannes Sixt j.s...@viscovery.net wrote: git gc moves unreachable objects that were packed before to the loose object store, from where they can be pruned. Thanks. That was the piece I was missing. I assumed `git gc` did the opposite. That begs a follow-up question. It sounds as though Git will typically delete unreachable objects. My team often shares links like https://git.example.com/foo.git/log/d59051721bb0a3758f7c6ea0452bac122a377645?hp=0055e0959cd13780494fe33832bae9bcf91e4a90 . If I later rebase the branch containing those commits and d590517 becomes unreachable, do I risk that link breaking when Git deletes d590517? What's a good strategy for avoiding breaking those links? -- Matt McClure http://matthewlmcclure.com http://www.mapmyfitness.com/profile/matthewlmcclure -- 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 v7 01/10] Add support for -i/--interactive to git-clean
Jiang Xin worldhello@gmail.com writes: Show what would be done and the user must confirm before actually cleaning. In the confirmation dialog, the user has three choices: * y/yes: Start to do cleaning. * n/no: Nothing will be deleted. * e/edit: Exclude items from deletion using ignore patterns. When the user chooses the edit mode, the user can input space- separated patterns (the same syntax as gitignore), and each clean candidate that matches with one of the patterns will be excluded from cleaning. When the user feels it's OK, presses ENTER and back to the confirmation dialog. Signed-off-by: Jiang Xin worldhello@gmail.com Suggested-by: Junio C Hamano gits...@pobox.com Spelling-checked-by: Eric Sunshine sunsh...@sunshineco.com Comments-by: Matthieu Moy matthieu@imag.fr Suggested-by: Eric Sunshine sunsh...@sunshineco.com Listing everybody who has ever said anything in the review thread? I can understand that you may want to give credit to those who significantly helped, but please do not overdo it. In any case, with the help of their inputs, you brought the patch into its final shape. Please sign-off at the _end_. --- Documentation/git-clean.txt | 15 +++- builtin/clean.c | 198 +++- 2 files changed, 192 insertions(+), 21 deletions(-) diff --git a/Documentation/git-clean.txt b/Documentation/git-clean.txt index bdc3a..f5572 100644 --- a/Documentation/git-clean.txt +++ b/Documentation/git-clean.txt @@ -8,7 +8,7 @@ git-clean - Remove untracked files from the working tree SYNOPSIS [verse] -'git clean' [-d] [-f] [-n] [-q] [-e pattern] [-x | -X] [--] path... +'git clean' [-d] [-f] [-i] [-n] [-q] [-e pattern] [-x | -X] [--] path... DESCRIPTION --- @@ -34,7 +34,18 @@ OPTIONS -f:: --force:: If the Git configuration variable clean.requireForce is not set - to false, 'git clean' will refuse to run unless given -f or -n. + to false, 'git clean' will refuse to run unless given -f, -n or + -i. + +-i:: +--interactive:: + Show what would be done and the user must confirm before actually + cleaning. In the confirmation dialog, the user can choose to abort + the cleaning, or enter into an edit mode. In the edit mode, the + user can input space-separated patterns (the same syntax as + gitignore), and each clean candidate that matches with one of the + patterns will be excluded from cleaning. When the user feels it's + OK, presses ENTER and back to the confirmation dialog. -n:: --dry-run:: diff --git a/builtin/clean.c b/builtin/clean.c index 04e39..49aab 100644 --- a/builtin/clean.c +++ b/builtin/clean.c @@ -15,9 +15,12 @@ #include quote.h static int force = -1; /* unset */ +static int interactive; +static struct string_list del_list = STRING_LIST_INIT_DUP; +static const char **the_prefix; Ehh, why? static const char *const builtin_clean_usage[] = { - N_(git clean [-d] [-f] [-n] [-q] [-e pattern] [-x | -X] [--] paths...), + N_(git clean [-d] [-f] [-i] [-n] [-q] [-e pattern] [-x | -X] [--] paths...), NULL }; @@ -142,6 +145,139 @@ static int remove_dirs(struct strbuf *path, const char *prefix, int force_flag, return ret; } +static void edit_by_patterns_cmd() static void edit_by_patterns_cmd(void) +{ + struct dir_struct dir; + struct strbuf confirm = STRBUF_INIT; + struct strbuf buf = STRBUF_INIT; + struct strbuf **ignore_list; + struct string_list_item *item; + struct exclude_list *el; + const char *qname; + int changed = -1, i; + + while (1) { + /* dels list may become empty when we run string_list_remove_empty_items later */ An unnecessary and overlong comment. The message shown already tells the reader what is going on anyway, no? + if (!del_list.nr) { + printf_ln(_(No more files to clean, exiting.)); + break; + } + + if (changed) { + putchar('\n'); + + /* Display dels in Would remove ... format */ + for_each_string_list_item(item, del_list) { + qname = quote_path_relative(item-string, -1, buf, *the_prefix); + printf(_(msg_would_remove), qname); + } + putchar('\n'); + } + + printf(_(Input ignore patterns )); + if (strbuf_getline(confirm, stdin, '\n') != EOF) { + strbuf_trim(confirm); + } else { + putchar('\n'); + break; Why break here? If we got nothing, wouldn't confirm.len be zero? If we did get something but the input got flushed without line-end, sending '\n' to the terminal may be justified, but in that case you would may have
Re: [PATCH v7 02/10] Show items of interactive git-clean in columns
Nice (I didn't read the code, though). -- 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 v7 04/10] git-clean: use a git-add-interactive compatible UI
Nice (I didn't read the code, though). -- 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 10/11] sha1_name: reorganize get_sha1_basic()
Felipe Contreras felipe.contre...@gmail.com writes: Through the years the functionality to handle @{-N} and @{u} has moved around the code, and as a result, code that once made sense, doesn't any more. There is no need to call this function recursively with the branch of @{-N} substituted because dwim_{ref,log} already replaces it. However, there's one corner-case where @{-N} resolves to a detached HEAD, in which case we wouldn't get any ref back. So we parse the nth-prior manually, and deal with it depending on weather it's a SHA-1, or a ref. ... s/weather/whether/; @@ -447,6 +448,10 @@ static int get_sha1_basic(const char *str, int len, unsigned char *sha1) if (len str[len-1] == '}') { for (at = len-4; at = 0; at--) { if (str[at] == '@' str[at+1] == '{') { + if (at == 0 str[2] == '-') { + nth_prior = 1; + continue; + } Does this have to be inside the loop? @@ -460,19 +465,22 @@ static int get_sha1_basic(const char *str, int len, unsigned char *sha1) if (len ambiguous_path(str, len)) return -1; - if (!len reflog_len) { + if (nth_prior) { struct strbuf buf = STRBUF_INIT; - int ret; - /* try the @{-N} syntax for n-th checkout */ - ret = interpret_branch_name(str, buf); - if (ret 0) - /* substitute this branch name and restart */ - return get_sha1_1(buf.buf, buf.len, sha1, 0); - else if (ret == 0) - return -1; + int detached; + + if (interpret_nth_prior_checkout(str, buf) 0) { + detached = (buf.len == 40 !get_sha1_hex(buf.buf, sha1)); + strbuf_release(buf); + if (detached) + return 0; + } + } Earlier, if @{-N} resolved to a detached head, we just fed it to get_sha1_1(). If it resolved to a concrete refname, we also fed it to get_sha1_1(). We ended up calling ourselves again and did the right thing either way. The new code bypasses the recursive call when we get a detached head back, because we know that calling get_sha1_1() with the 40-hex will eventually take us back to this codepath, and immediately return when it sees get_sha1_hex() succeeds. What happens when str @{-N} leaves a concrete refname in buf.buf? The branch name is lost with strbuf_release(), and then where do we go from here? Continuing down from here would run dwim_ref/log on str which is still @{-N}, no? Ahh, OK, the new code will now let dwim_ref/log to process @{-N} again (the log message hints this but it wasn't all that clear), so even though we already learned the branch name in buf here and discard it, we will eventually discover the same information later. That is somewhat contrived, and I am not so sure if that is a good reorganization. Also, a few points this patch highlights in the code before the change: - If we were on a branch with 40-hex name at nth prior checkout, would we mistake it as being detached at the commit? - If we were on a branch 'foo' at nth prior checkout, would our previous get_sha1_1() have made us mistake it as referring to a tag 'foo' with the same name if it exists? The former needs a fix to either writing of reflog or reading by interpret_nth_prior_checkout() so that we can tell these cases apart more reliably. Then the latter can be solved by splicing refs/heads/ in front of the branch name before recursively calling get_sha1_1() in the original code (and similar fix can be forward-ported to this patch). Incidentally, I think if we prefix refs/heads/ in front and feed that to dwim_ref/log, we would also avoid running @{-N} twice (which I suspect might be more expensive than a simple recursion, as it needs to go through the reflog file), which may be a nice side effect of such a fix we would get for free. + + if (!len reflog_len) /* allow @{...} to mean the current branch reflog */ refs_found = dwim_ref(HEAD, 4, sha1, real_ref); - } else if (reflog_len) + else if (reflog_len) refs_found = dwim_log(str, len, sha1, real_ref); else refs_found = dwim_ref(str, len, sha1, real_ref); -- 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 10/11] sha1_name: reorganize get_sha1_basic()
Junio C Hamano gits...@pobox.com writes: Also, a few points this patch highlights in the code before the change: - If we were on a branch with 40-hex name at nth prior checkout, would we mistake it as being detached at the commit? - If we were on a branch 'foo' at nth prior checkout, would our previous get_sha1_1() have made us mistake it as referring to a tag 'foo' with the same name if it exists? The former needs a fix to either writing of reflog or reading by interpret_nth_prior_checkout() so that we can tell these cases apart more reliably. Then the latter can be solved by splicing refs/heads/ in front of the branch name before recursively calling get_sha1_1() in the original code (and similar fix can be forward-ported to this patch). Incidentally, I think if we prefix refs/heads/ in front and feed that to dwim_ref/log, we would also avoid running @{-N} twice (which I suspect might be more expensive than a simple recursion, as it needs to go through the reflog file), which may be a nice side effect of such a fix we would get for free. Here is the first step (i.e. more reliable interpret_nth_prior). I looked at all the existing callers of interpret_branch_name() and it appears to me that most of them currently assume they are getting a branch name, because they want to work on a ref, and some of them do not care, because they are working on a revision. For the former, they can (and should) error out instead of relying on not having refs/heads/$detached_SHA1 that will prevent them from working on a ref which is what they currently do, if they had the detached information. For the latter, if we give detached information, they can either prefix refs/heads/ (if the result is not detached) to call resolve_ref(), or call get_sha1_hex (if the result is detached), which would be the solution for the second issue I noticed in the message I am replying to. The next step on top of this patch may be to expose the detached bit up in the API chain to let callers of interpret_branch_name() to know about the distinction. sha1_name.c | 12 ++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/sha1_name.c b/sha1_name.c index 3820f28..3dd6667 100644 --- a/sha1_name.c +++ b/sha1_name.c @@ -862,6 +862,7 @@ static int get_sha1_oneline(const char *prefix, unsigned char *sha1, struct grab_nth_branch_switch_cbdata { int remaining; struct strbuf buf; + int detached; }; static int grab_nth_branch_switch(unsigned char *osha1, unsigned char *nsha1, @@ -880,9 +881,14 @@ static int grab_nth_branch_switch(unsigned char *osha1, unsigned char *nsha1, if (!match || !target) return 0; if (--(cb-remaining) == 0) { + unsigned char sha1[20]; + len = target - match; strbuf_reset(cb-buf); strbuf_add(cb-buf, match, len); + cb-detached = (len == 40 + !get_sha1_hex(match, sha1) + !hashcmp(osha1, sha1)); return 1; /* we are done */ } return 0; @@ -892,7 +898,7 @@ static int grab_nth_branch_switch(unsigned char *osha1, unsigned char *nsha1, * Parse @{-N} syntax, return the number of characters parsed * if successful; otherwise signal an error with negative value. */ -static int interpret_nth_prior_checkout(const char *name, struct strbuf *buf) +static int interpret_nth_prior_checkout(const char *name, struct strbuf *buf, int *detached) { long nth; int retval; @@ -917,6 +923,8 @@ static int interpret_nth_prior_checkout(const char *name, struct strbuf *buf) if (0 for_each_reflog_ent_reverse(HEAD, grab_nth_branch_switch, cb)) { strbuf_reset(buf); strbuf_add(buf, cb.buf.buf, cb.buf.len); + if (detached) + *detached = cb.detached; retval = brace - name + 1; } @@ -992,7 +1000,7 @@ int interpret_branch_name(const char *name, struct strbuf *buf) char *cp; struct branch *upstream; int namelen = strlen(name); - int len = interpret_nth_prior_checkout(name, buf); + int len = interpret_nth_prior_checkout(name, buf, NULL); int tmp_len; if (!len) -- 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: [BUG] shallow clones over http
Jeff King p...@peff.net writes: I'm trying to track down a protocol bug that happens with shallow clones over smart-http. As far as I can tell, the bug has existed in all versions. You can reproduce it using the attached repository, which is a shallow clone of https://github.com/mileszs/ack.vim.git, like: $ tar xzf repo.tar.gz $ cd repo.git $ git fetch --depth=10 fatal: git fetch-pack: expected shallow list In that test my fetch actually hit github.com as the upstream full repo, but you can also clone it down locally and demonstrate it with purely local copies of git (but it's more of a pain, because you have to set up a smart http server). The last part of the conversation looks like this: packet: fetch-pack packet: fetch-pack ACK f183a345a0c10caed7684d07dabae33e007c7590 common packet: fetch-pack have f183a345a0c10caed7684d07dabae33e007c7590 packet: fetch-pack ACK 33312d4db4e91468957b1b41dd039c5d88e85fda common packet: fetch-pack ACK 34d0b2fbc182b31d926632d170bc07d6a6fc3f9b common packet: fetch-pack ACK 45c802e07c60686986474b6b05b2c7048330b6b5 common packet: fetch-pack ACK e93f693fd2a9940d6421bf9e4ddd1f535994eaa5 common packet: fetch-pack ACK 132ee41e8e2c8c545b3aed120171e1596c9211a4 common packet: fetch-pack ACK 973deb3145a2638b2301cfd654721cf35d68 common packet: fetch-pack ACK e53a88a4e72d84562493313e8911ada4def787da common packet: fetch-pack ACK 90be0bf3eee6f7a0cb9c2377a50610f4ce738da3 common packet: fetch-pack ACK aeab88ccf41bf216fde37983bd403d9b913391e7 common packet: fetch-pack ACK 5f480935d3ce431c393657c3000337bcbdbd5535 common packet: fetch-pack ACK db81e01b433501b159983ea38690aeb01eea1e6b common packet: fetch-pack ACK 06c44b8cab93e780a29ff7f7b5b1dd41dba4b2d5 common packet: fetch-pack ACK 65f3966becdb2d931d5afbdcc6a28008d154668a common packet: fetch-pack ACK 10e8caef9f2ed308231ce1abc326c512e86a5d4c common packet: fetch-pack ACK 6b55dd91f2e7fc64c23eea57e85171cb958f9cd2 common packet: fetch-pack ACK 6b55dd91f2e7fc64c23eea57e85171cb958f9cd2 ready packet: fetch-pack NAK packet: fetch-pack ACK 6b55dd91f2e7fc64c23eea57e85171cb958f9cd2 fatal: git fetch-pack: expected shallow list So we see that upload-pack sends a bunch of detailed ACKs, followed by a NAK, and then it sends another ACK. Fetch-pack is inside find_common, reading these acks. At the beginning of each stateless-rpc response, it expects to consume any shallow/unshallow lines up to a flush packet (the call to consume_shallow_list). And then it reads the acks in a loop. After it sees the NAK, it assumes that the server is done sending the packet, and loops again, expecting another set of shallow/unshallow lines. But we get the next ACK instead, and die. So who is wrong? Is upload-pack wrong to send an ACK after the NAK? 3e63b21aced1 (upload-pack: Implement no-done capability, 2011-03-14) claims that the above sequence of acks and naks is what upload-pack wants to show. What happens when you disable no-done extension handling on the server end, I wonder? -- 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
[PATCHv2] CodingGuidelines: make it clear which files in Documentation/ are the sources
From e87227498ef3d50dc20584c24c53071cce63c555 Mon Sep 17 00:00:00 2001 From: Dale Worley wor...@ariadne.com Date: Tue, 7 May 2013 13:39:46 -0400 Subject: [PATCH] CodingGuidelines: make it clear which files in Documentation/ are the sources Signed-off-by: Dale R. Worley wor...@ariadne.com --- While learning about making a documentation patch, I noticed that Documentation/CodingGuideles isn't as clear as it could be regarding how to edit the documentation. In particular, it says Most (if not all) of the documentation pages are written in AsciiDoc - and processed into HTML output and manpages. without really specifying the details for those of us who aren't familiar with AsciiDoc. So I added a sentence stating explicitly which files are the sources and which are derived. It's also a test for submitting a patch. I've read SubmittingPatches again, more carefully, and have corrected some problem with my previous message. Documentation/CodingGuidelines |4 +++- 1 files changed, 3 insertions(+), 1 deletions(-) diff --git a/Documentation/CodingGuidelines b/Documentation/CodingGuidelines index 7e4d571..b8eef7c 100644 --- a/Documentation/CodingGuidelines +++ b/Documentation/CodingGuidelines @@ -238,7 +238,9 @@ For Python scripts: Writing Documentation: Most (if not all) of the documentation pages are written in AsciiDoc - and processed into HTML output and manpages. + and processed into HTML output and manpages. This means that the *.txt + files in this directory are usually the sources from which the + corresponding *.html, *.1, and *.xml files are generated. Every user-visible change should be reflected in the documentation. The same general rule as for code applies -- imitate the existing -- 1.7.7.6 -- 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 10/11] sha1_name: reorganize get_sha1_basic()
On Wed, May 8, 2013 at 1:18 PM, Junio C Hamano gits...@pobox.com wrote: Felipe Contreras felipe.contre...@gmail.com writes: Through the years the functionality to handle @{-N} and @{u} has moved around the code, and as a result, code that once made sense, doesn't any more. There is no need to call this function recursively with the branch of @{-N} substituted because dwim_{ref,log} already replaces it. However, there's one corner-case where @{-N} resolves to a detached HEAD, in which case we wouldn't get any ref back. So we parse the nth-prior manually, and deal with it depending on weather it's a SHA-1, or a ref. ... s/weather/whether/; @@ -447,6 +448,10 @@ static int get_sha1_basic(const char *str, int len, unsigned char *sha1) if (len str[len-1] == '}') { for (at = len-4; at = 0; at--) { if (str[at] == '@' str[at+1] == '{') { + if (at == 0 str[2] == '-') { + nth_prior = 1; + continue; + } Does this have to be inside the loop? Yes, the whole purpose is to avoid reflog_len to be set. @@ -460,19 +465,22 @@ static int get_sha1_basic(const char *str, int len, unsigned char *sha1) if (len ambiguous_path(str, len)) return -1; - if (!len reflog_len) { + if (nth_prior) { struct strbuf buf = STRBUF_INIT; - int ret; - /* try the @{-N} syntax for n-th checkout */ - ret = interpret_branch_name(str, buf); - if (ret 0) - /* substitute this branch name and restart */ - return get_sha1_1(buf.buf, buf.len, sha1, 0); - else if (ret == 0) - return -1; + int detached; + + if (interpret_nth_prior_checkout(str, buf) 0) { + detached = (buf.len == 40 !get_sha1_hex(buf.buf, sha1)); + strbuf_release(buf); + if (detached) + return 0; + } + } Earlier, if @{-N} resolved to a detached head, we just fed it to get_sha1_1(). If it resolved to a concrete refname, we also fed it to get_sha1_1(). We ended up calling ourselves again and did the right thing either way. The new code bypasses the recursive call when we get a detached head back, because we know that calling get_sha1_1() with the 40-hex will eventually take us back to this codepath, and immediately return when it sees get_sha1_hex() succeeds. What happens when str @{-N} leaves a concrete refname in buf.buf? The branch name is lost with strbuf_release(), and then where do we go from here? Continuing down from here would run dwim_ref/log on str which is still @{-N}, no? Ahh, OK, the new code will now let dwim_ref/log to process @{-N} again (the log message hints this but it wasn't all that clear), I thought it was clear we would let dwim_{ref,log} do the job: --- There is no need to call this function recursively with the branch of @{-N} substituted because dwim_{ref,log} already replaces it. --- That is somewhat contrived, and I am not so sure if that is a good reorganization. But much less contrived than before, because the code that deals with @{-N} is in one place, instead of sprinkled all over as many corner-cases, and there's no recursion. Also, a few points this patch highlights in the code before the change: - If we were on a branch with 40-hex name at nth prior checkout, would we mistake it as being detached at the commit? - If we were on a branch 'foo' at nth prior checkout, would our previous get_sha1_1() have made us mistake it as referring to a tag 'foo' with the same name if it exists? I don't know, but I suspect there's no change after this patch. -- 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 1/2] sha1_name.c: signal if @{-N} was a true branch nameor a detached head
The original API read checkout: moving from (.*) to ... from the reflog of the HEAD, and returned the substring between from and to, but there was no way, if the substring was a 40-hex string, to tell if we were on a detached HEAD at that commit object, or on a branch whose name happened to be the 40-hex string. At this point, we cannot afford to change the format recorded in the reflog, so introduce a heuristics to see if the 40-hex matches the object name of the commit we are switching out of. This will unfortunately mishandle this case: HEX=$(git rev-parse master) git checkout -b $HEX master git checkout master where we were indeed on a non-detached $HEX branch (i.e. HEAD was pointing at refs/heads/$HEX, not storing $HEX), of course, but otherwise should be fairly reliable. Signed-off-by: Junio C Hamano gits...@pobox.com --- * This is a preparatory step for the beginning of a much larger series. Peff is Cc'ed because one of the most tricky issue involves what d46a8301930a (fix parsing of @{-1}@{u} combination, 2010-01-28) did. sha1_name.c | 16 ++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/sha1_name.c b/sha1_name.c index 3820f28..1473bb6 100644 --- a/sha1_name.c +++ b/sha1_name.c @@ -862,6 +862,7 @@ static int get_sha1_oneline(const char *prefix, unsigned char *sha1, struct grab_nth_branch_switch_cbdata { int remaining; struct strbuf buf; + int detached; }; static int grab_nth_branch_switch(unsigned char *osha1, unsigned char *nsha1, @@ -880,9 +881,14 @@ static int grab_nth_branch_switch(unsigned char *osha1, unsigned char *nsha1, if (!match || !target) return 0; if (--(cb-remaining) == 0) { + unsigned char sha1[20]; + len = target - match; strbuf_reset(cb-buf); strbuf_add(cb-buf, match, len); + cb-detached = (len == 40 + !get_sha1_hex(match, sha1) + !hashcmp(osha1, sha1)); return 1; /* we are done */ } return 0; @@ -891,8 +897,12 @@ static int grab_nth_branch_switch(unsigned char *osha1, unsigned char *nsha1, /* * Parse @{-N} syntax, return the number of characters parsed * if successful; otherwise signal an error with negative value. + * The string in buf.buf is either a branch name (needs to be + * prefixed with refs/heads/ if the caller wants to make it + * a fully spelled refname) or 40-hex object name of the detached + * HEAD, and *detached is set to true for the latter. */ -static int interpret_nth_prior_checkout(const char *name, struct strbuf *buf) +static int interpret_nth_prior_checkout(const char *name, struct strbuf *buf, int *detached) { long nth; int retval; @@ -917,6 +927,8 @@ static int interpret_nth_prior_checkout(const char *name, struct strbuf *buf) if (0 for_each_reflog_ent_reverse(HEAD, grab_nth_branch_switch, cb)) { strbuf_reset(buf); strbuf_add(buf, cb.buf.buf, cb.buf.len); + if (detached) + *detached = cb.detached; retval = brace - name + 1; } @@ -992,7 +1004,7 @@ int interpret_branch_name(const char *name, struct strbuf *buf) char *cp; struct branch *upstream; int namelen = strlen(name); - int len = interpret_nth_prior_checkout(name, buf); + int len = interpret_nth_prior_checkout(name, buf, NULL); int tmp_len; if (!len) -- 1.8.3-rc1-182-gc61d106 -- 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/2] interpret_branch_name(): unconfuse @{-1}@{u} when @{-1} is detached
Now interpret_nth_prior_checkout() can tell the caller if the result of expansion of @{-1} is a real branch name or the commit object name for a detached HEAD state, let's avoid re-interpreting $HEX@{u} in the latter case. Signed-off-by: Junio C Hamano gits...@pobox.com --- * This prevents us from mistakenly refering to the upstream of an unrelated branch in this sequence: HEX=$(git rev-parse --verify HEAD) git branch $HEX git checkout HEAD^0 git checkout - git log @{-1}@{u} The branch created in the first step has never been checked out, and @{-1} does not refer to it. @{-1}@{u} would first turn into $HEX@{u} but we should not look for upstream of refs/heads/$HEX. sha1_name.c | 12 +--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/sha1_name.c b/sha1_name.c index 1473bb6..d3b6897 100644 --- a/sha1_name.c +++ b/sha1_name.c @@ -1004,15 +1004,21 @@ int interpret_branch_name(const char *name, struct strbuf *buf) char *cp; struct branch *upstream; int namelen = strlen(name); - int len = interpret_nth_prior_checkout(name, buf, NULL); + int detached; + int len = interpret_nth_prior_checkout(name, buf, detached); int tmp_len; if (!len) return len; /* syntax Ok, not enough switches */ if (0 len len == namelen) return len; /* consumed all */ - else if (0 len) { - /* we have extra data, which might need further processing */ + else if (0 len !detached) { + /* +* We have extra data, which might need further +* processing. E.g. for the original @{-1}@{u} we +* have converted @{-1} into buf and yet to process +* the remaining @{u} part. +*/ struct strbuf tmp = STRBUF_INIT; int used = buf-len; int ret; -- 1.8.3-rc1-182-gc61d106 -- 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
[non PATCH */2] preparatory analysis of remaining @{...} issues
Currently interpret_branch_name() takes either @{-N}, @{u}, or some@{u} and returns an abbreviated refname, or a detached HEAD if @{-N} resolves to such a state. Local branch names coming back for @{-N} are returned as branch names without refs/heads/, upstream names coming back for @{u} are given after cleaning it up with shorten_unambiguous_ref(). @{-N} resolved to a detached HEAD yields a bare 40-HEX. This makes the caller unnecessarily fragile. I started asking (1) perhaps interpret_branch_name() can be updated to return a full refname when it does return a ref; (2) perhaps it can also be updated to say if its input @{-N} refers to a detached HEAD state. I looked at all existing callers of interpret_branch_name() to see how feasible such a change is. Here is a preparatory analysis. refs.c: substitute_branch_name() The call to interpret_branch_name() by this function only wants to see the branch name replaced to a full refname for the consumption of dwim_ref() and dwim_log(), and does not want to see a detached HEAD state at all. Changing @{-N} that returns the bare branch name to return refs/heads/$name is welcome. Changing $name@{u} that returns an abbreviation to return a full refname is also welcome. And we can error out early if @{-N} referred to a detached HEAD. [answer: Yes/Yes] revision.c: add_pending_object_with_mode() The call to interpret_branch_name() by this function wants to turn @{-N} and $name@{u} to a refname so that it can be passed to add_reflog_for_walk(). Obviously it does not want to see a detached state. Again, this benefits if interpret_branch_name returned a full refname, as add_reflog_for_walk() eventually ends up passing the name to dwim_log(). [answer: Yes/Yes] sha1_name.c: get_sha1_basic() The call to interpret_branch_name() by this function wants to turn @{-N} and $name@{u} to a string that can be fed to get_sha1_1() to get an object name. Returning full refname or full object name is a good change. [answer: Yes/Yes] sha1_name.c: interpret_branch_name() @{-N}@{u} is first given to interpret_nth_prior_checkout() to turn @{-N} into a branch name, and then appends @{u} to the result and recursively call this function to expand $branch@{u}. Expansion of @{-N} to full refname can break the second expansion, and needs to be adjusted, but if @{-N} turns out to be a detaches state, we would want to error out the resulting $HEX@{u} anyway, so updating the API would result in a pair of real bug fixes. [answer: Yes/Yes -- but this caller needs further adjustment] sha1_name.c: strbuf_branchname() The function wants to return an abbreviated branch name. The callers of this function are: builtin/branch.c: delete_branches() git branch -d -r master@{u} may expand to git branch -d -r origin/master and delete refs/remotes/origin/master, and git branch -d @{-2} would expand to git branch -d next and delete refs/heads/next. strbuf_branchname() that returns a full refname would break this caller and the caller needs to be updated to shorten its output. But if strbuf_branchname() can tell @{-N} were detached, we can prevent removal of an unintended local branch. builtin/checkout.c: setup_branch_path() With the current code, git checkout -b master@{u} would expand to git checkout -b origin/master and end up creating refs/heads/origin/master, which may not be a good thing. strbuf_branchname() that returns a full refname would break this caller and the caller needs to be updated to shorten its output. If strbuf_branchname() can tell @{-N} were detached, we can error out instead of creating a bogus local branch. builtin/merge.c: merge_name() Uses strbuf_branchname() to turn @{-N} and $name@{u} into something that can be fed to dwim_ref(). This does benefit if strbuf_branchname() can find out the full refname. If strbuf_branchname() can tell @{-N} were detached, we can error out instead of creating a bogus local branch. sha1_name.c: strbuf_check_branch_ref() Used to see if the name is reasonable when appended to refs/heads/. strbuf_branchname() that returns a full refname would break this caller and the caller needs to be updated to shorten its output. So strbuf_branchname() itself can tolerate an updated interpret_branch_name() that returns full refname and it will benefit if it can learn about detached state (many of its callers would appreciate the latter). [answer: Yes/Yes -- but this caller and its callers need some adjustment]. -- To unsubscribe from this list: send the line unsubscribe git in the body of a message to majord...@vger.kernel.org More
Re: [PATCH v2 10/11] sha1_name: reorganize get_sha1_basic()
Felipe Contreras felipe.contre...@gmail.com writes: On Wed, May 8, 2013 at 1:18 PM, Junio C Hamano gits...@pobox.com wrote: Felipe Contreras felipe.contre...@gmail.com writes: Through the years the functionality to handle @{-N} and @{u} has moved around the code, and as a result, code that once made sense, doesn't any more. There is no need to call this function recursively with the branch of @{-N} substituted because dwim_{ref,log} already replaces it. However, there's one corner-case where @{-N} resolves to a detached HEAD, in which case we wouldn't get any ref back. So we parse the nth-prior manually, and deal with it depending on weather it's a SHA-1, or a ref. ... s/weather/whether/; @@ -447,6 +448,10 @@ static int get_sha1_basic(const char *str, int len, unsigned char *sha1) if (len str[len-1] == '}') { for (at = len-4; at = 0; at--) { if (str[at] == '@' str[at+1] == '{') { + if (at == 0 str[2] == '-') { + nth_prior = 1; + continue; + } Does this have to be inside the loop? Yes, the whole purpose is to avoid reflog_len to be set. What I meant was the nothing@{- check, which happens only at==0. if (!memcmp(str, @{-, 3) len 3) nth_prior = 1; else for (at = len - 4; at; at--) { ... look for and break at the first @{ ... } or something. Ahh, OK, the new code will now let dwim_ref/log to process @{-N} again (the log message hints this but it wasn't all that clear), I thought it was clear we would let dwim_{ref,log} do the job: Yes, the reason I did not immediately think of that is because I knew @{-N} was expensive (need to read reflog backwards) and didn't think anybody would redo the code to deliberately do that twice ;-) Also, a few points this patch highlights in the code before the change: - If we were on a branch with 40-hex name at nth prior checkout, would we mistake it as being detached at the commit? - If we were on a branch 'foo' at nth prior checkout, would our previous get_sha1_1() have made us mistake it as referring to a tag 'foo' with the same name if it exists? I don't know, but I suspect there's no change after this patch. Yes, didn't I say the code before the change above? These two correctness issues look more important issues to me, with or without the restructure patch (in other words, they are independent). -- 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 10/11] sha1_name: reorganize get_sha1_basic()
On Wed, May 8, 2013 at 4:51 PM, Junio C Hamano gits...@pobox.com wrote: Felipe Contreras felipe.contre...@gmail.com writes: On Wed, May 8, 2013 at 1:18 PM, Junio C Hamano gits...@pobox.com wrote: Felipe Contreras felipe.contre...@gmail.com writes: Through the years the functionality to handle @{-N} and @{u} has moved around the code, and as a result, code that once made sense, doesn't any more. There is no need to call this function recursively with the branch of @{-N} substituted because dwim_{ref,log} already replaces it. However, there's one corner-case where @{-N} resolves to a detached HEAD, in which case we wouldn't get any ref back. So we parse the nth-prior manually, and deal with it depending on weather it's a SHA-1, or a ref. ... s/weather/whether/; @@ -447,6 +448,10 @@ static int get_sha1_basic(const char *str, int len, unsigned char *sha1) if (len str[len-1] == '}') { for (at = len-4; at = 0; at--) { if (str[at] == '@' str[at+1] == '{') { + if (at == 0 str[2] == '-') { + nth_prior = 1; + continue; + } Does this have to be inside the loop? Yes, the whole purpose is to avoid reflog_len to be set. What I meant was the nothing@{- check, which happens only at==0. if (!memcmp(str, @{-, 3) len 3) nth_prior = 1; else for (at = len - 4; at; at--) { ... look for and break at the first @{ ... } or something. That's doable, but would screw up the next patch. Ahh, OK, the new code will now let dwim_ref/log to process @{-N} again (the log message hints this but it wasn't all that clear), I thought it was clear we would let dwim_{ref,log} do the job: Yes, the reason I did not immediately think of that is because I knew @{-N} was expensive (need to read reflog backwards) and didn't think anybody would redo the code to deliberately do that twice ;-) But that's what the commit message said. Also, a few points this patch highlights in the code before the change: - If we were on a branch with 40-hex name at nth prior checkout, would we mistake it as being detached at the commit? - If we were on a branch 'foo' at nth prior checkout, would our previous get_sha1_1() have made us mistake it as referring to a tag 'foo' with the same name if it exists? I don't know, but I suspect there's no change after this patch. Yes, didn't I say the code before the change above? These two correctness issues look more important issues to me, with or without the restructure patch (in other words, they are independent). Right, if you are interested in correctness, you might want to try @{-1}{0}; it resolves to @{-1} currently, and it fails correctly with my patch. 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 1/2] help: add help_unknown_ref
Vikrant Varma vikrant.varm...@gmail.com writes: When a ref is not known, currently functions call die() with an error message. The first part read somewhat awkward, so I started rewriting the above like so: When the user gives an unknown string to a command that expects to see a ref, we could be more helpful than just saying that's not a ref and die. which in turn made me realize that some commands may not even know if the user mistyped a ref. It is not an objection to this patch per-se, but a useful future enhancement may be to allow the callers call guess_mistyped_ref() directly and let them decide what to do when they suspect the string they did not understand is not a mistyped ref but something else, i.e. not let help_unknown_ref() die unconditionally but allow it to return. Then the caller can do: commit = get_commit_from_string(argv[i]); if (!commit) { ... I do not understand argv[i], but ... ... it may be a mistyped ref ... help_unknown_ref(argv[i], expected a revision); ... it is not likely to be a typo ... ... perhaps it was meant to be a filename? ... if (file_exists(argv[i])) { ... yes! ... ... do the file thing instead ... } } Add helper function help_unknown_ref to take care of displaying an error message along with a list of suggested refs the user might have meant. OK. Example: $ git merge foo merge: foo - not something we can merge That leading merge: looks somewhat strange, especially when it immediately follows the command line to invoke merge, making it appear to waste space by stating the obvious. Our messages are generally marked with error:, fatal:, warning:, etc. at the beginning. Did you mean one of these? origin/foo upstream/foo Signed-off-by: Vikrant Varma vikrant.varm...@gmail.com ... +struct string_list guess_refs(const char *ref) +{ + struct similar_ref_cb ref_cb; + struct string_list similar_refs = STRING_LIST_INIT_NODUP; + + ref_cb.base_ref = ref; + ref_cb.similar_refs = similar_refs; + for_each_ref(append_similar_ref, ref_cb); + return similar_refs; +} + +void help_unknown_ref(const char *ref, const char *cmd, const char *error) +{ + int i; + struct string_list suggested_refs = guess_refs(ref); + + fprintf_ln(stderr, _(%s: %s - %s), cmd, ref, error); + + if (suggested_refs.nr 0) { + fprintf_ln(stderr, +Q_(\nDid you mean this?, + \nDid you mean one of these?, + suggested_refs.nr)); + for (i = 0; i suggested_refs.nr; i++) + fprintf(stderr, \t%s\n, suggested_refs.items[i].string); + } + + string_list_clear(suggested_refs, 0); + exit(1); +} Looks sensible. diff --git a/help.h b/help.h index 0ae5a12..5003423 100644 --- a/help.h +++ b/help.h @@ -27,4 +27,9 @@ extern void exclude_cmds(struct cmdnames *cmds, struct cmdnames *excludes); extern int is_in_cmdlist(struct cmdnames *cmds, const char *name); extern void list_commands(unsigned int colopts, struct cmdnames *main_cmds, struct cmdnames *other_cmds); +/* + * This function has been called because ref is not known. + * Print a list of refs that the user might have meant, and exit. + */ The wording is a bit funny; I'll amend it somehow before queuing. +extern void help_unknown_ref(const char *ref, const char *cmd, const char *error); #endif /* HELP_H */ -- 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 4/5] git-svn: fix bottleneck in stash_placeholder_list()
Ilya Basin basini...@gmail.com wrote: Hi Eric. I'm out of spare time and I still unable to import my repo. The code of SVN.pm is too complex. Please help me. Sorry, most what I do nowadays for git-svn is ACK/NACK changes. git-svn has made itself obsolete for most contributors, myself included; so it's hard for us to devote significant amounts of time on it since we no longer see SVN repos in our day-to-day work. Given the differences between branching/tagging in SVN and git, I suspect some history may always be too complex/convoluted to automatically import. Perhaps an interactive mode can be introduced to follow history... Anyways, thank you for documenting these issues and suggesting fixes. Hopefully somebody with sufficient motivation can continue your work down the line. -- 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] Git::SVN::*: add missing NAME section to perldoc
Jonathan Nieder jrnie...@gmail.com wrote: Just noticed this by running a tool to sanity-check my build result. I hadn't noticed before because I hadn't been installing the manpages. Anyway, perhaps the patch can be useful. Thanks, signed-off and applied, will push. -- 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/4] trivial patches
Hi, Here's a bunch of trivial style cleanup patches. Felipe Contreras (4): documentation: trivial style cleanups transport-helper: trivial style cleanup {fast-export,transport-helper}: style cleanups fast-export: trivial cleanup Documentation/git-am.txt | 7 +++ Documentation/git-archive.txt | 2 +- Documentation/git-check-ref-format.txt | 3 +-- Documentation/git-clone.txt| 4 ++-- Documentation/git-commit.txt | 2 +- Documentation/git-config.txt | 3 +-- Documentation/git-daemon.txt | 5 ++--- Documentation/git-difftool.txt | 3 +-- Documentation/git-fast-export.txt | 10 +- Documentation/git-fetch-pack.txt | 6 +++--- Documentation/git-fmt-merge-msg.txt| 3 +-- Documentation/git-fsck.txt | 6 ++ Documentation/git-grep.txt | 2 +- Documentation/git-mailinfo.txt | 2 +- Documentation/git-merge.txt| 3 +-- Documentation/git-mergetool.txt| 2 +- Documentation/git-push.txt | 3 +-- Documentation/git-remote.txt | 2 +- Documentation/git-revert.txt | 2 +- Documentation/git-update-index.txt | 10 -- builtin/fast-export.c | 29 + transport-helper.c | 3 +-- 22 files changed, 48 insertions(+), 64 deletions(-) -- 1.8.3.rc1.553.gac13664 -- 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/4] documentation: trivial style cleanups
White-spaces, missing braces, standardize --[no-]foo. Signed-off-by: Felipe Contreras felipe.contre...@gmail.com --- Documentation/git-am.txt | 7 +++ Documentation/git-archive.txt | 2 +- Documentation/git-check-ref-format.txt | 3 +-- Documentation/git-clone.txt| 4 ++-- Documentation/git-commit.txt | 2 +- Documentation/git-config.txt | 3 +-- Documentation/git-daemon.txt | 5 ++--- Documentation/git-difftool.txt | 3 +-- Documentation/git-fast-export.txt | 10 +- Documentation/git-fetch-pack.txt | 6 +++--- Documentation/git-fmt-merge-msg.txt| 3 +-- Documentation/git-fsck.txt | 6 ++ Documentation/git-grep.txt | 2 +- Documentation/git-mailinfo.txt | 2 +- Documentation/git-merge.txt| 3 +-- Documentation/git-mergetool.txt| 2 +- Documentation/git-push.txt | 3 +-- Documentation/git-remote.txt | 2 +- Documentation/git-revert.txt | 2 +- Documentation/git-update-index.txt | 10 -- 20 files changed, 34 insertions(+), 46 deletions(-) diff --git a/Documentation/git-am.txt b/Documentation/git-am.txt index 19d57a8..5bbe7b6 100644 --- a/Documentation/git-am.txt +++ b/Documentation/git-am.txt @@ -9,12 +9,12 @@ git-am - Apply a series of patches from a mailbox SYNOPSIS [verse] -'git am' [--signoff] [--keep] [--keep-cr | --no-keep-cr] [--utf8 | --no-utf8] +'git am' [--signoff] [--keep] [--[no-]keep-cr] [--[no-]utf8] [--3way] [--interactive] [--committer-date-is-author-date] [--ignore-date] [--ignore-space-change | --ignore-whitespace] [--whitespace=option] [-Cn] [-pn] [--directory=dir] [--exclude=path] [--include=path] [--reject] [-q | --quiet] -[--scissors | --no-scissors] +[--[no-]scissors] [(mbox | Maildir)...] 'git am' (--continue | --skip | --abort) @@ -43,8 +43,7 @@ OPTIONS --keep-non-patch:: Pass `-b` flag to 'git mailinfo' (see linkgit:git-mailinfo[1]). ---keep-cr:: ---no-keep-cr:: +--[no-]keep-cr:: With `--keep-cr`, call 'git mailsplit' (see linkgit:git-mailsplit[1]) with the same option, to prevent it from stripping CR at the end of lines. `am.keepcr` configuration variable can be used to specify the diff --git a/Documentation/git-archive.txt b/Documentation/git-archive.txt index 250e522..b97aaab 100644 --- a/Documentation/git-archive.txt +++ b/Documentation/git-archive.txt @@ -10,7 +10,7 @@ SYNOPSIS [verse] 'git archive' [--format=fmt] [--list] [--prefix=prefix/] [extra] - [-o | --output=file] [--worktree-attributes] + [-o file | --output=file] [--worktree-attributes] [--remote=repo [--exec=git-upload-archive]] tree-ish [path...] diff --git a/Documentation/git-check-ref-format.txt b/Documentation/git-check-ref-format.txt index ec1739a..a49be1b 100644 --- a/Documentation/git-check-ref-format.txt +++ b/Documentation/git-check-ref-format.txt @@ -83,8 +83,7 @@ typed the branch name. OPTIONS --- ---allow-onelevel:: ---no-allow-onelevel:: +--[no-]allow-onelevel:: Controls whether one-level refnames are accepted (i.e., refnames that do not contain multiple `/`-separated components). The default is `--no-allow-onelevel`. diff --git a/Documentation/git-clone.txt b/Documentation/git-clone.txt index 5c16e31..a0727d7 100644 --- a/Documentation/git-clone.txt +++ b/Documentation/git-clone.txt @@ -14,7 +14,7 @@ SYNOPSIS [-o name] [-b name] [-u upload-pack] [--reference repository] [--separate-git-dir git dir] [--depth depth] [--[no-]single-branch] - [--recursive|--recurse-submodules] [--] repository + [--recursive | --recurse-submodules] [--] repository [directory] DESCRIPTION @@ -188,7 +188,7 @@ objects from the source repository into a pack in the cloned repository. with a long history, and would want to send in fixes as patches. ---single-branch:: +--[no-]single-branch:: Clone only the history leading to the tip of a single branch, either specified by the `--branch` option or the primary branch remote's `HEAD` points at. When creating a shallow diff --git a/Documentation/git-commit.txt b/Documentation/git-commit.txt index 8172938..1a7616c 100644 --- a/Documentation/git-commit.txt +++ b/Documentation/git-commit.txt @@ -12,7 +12,7 @@ SYNOPSIS [--dry-run] [(-c | -C | --fixup | --squash) commit] [-F file | -m msg] [--reset-author] [--allow-empty] [--allow-empty-message] [--no-verify] [-e] [--author=author] - [--date=date] [--cleanup=mode] [--status | --no-status] + [--date=date] [--cleanup=mode] [--[no-]status] [-i | -o] [-S[keyid]] [--] [file...] DESCRIPTION diff --git a/Documentation/git-config.txt
[PATCH 2/4] transport-helper: trivial style cleanup
Signed-off-by: Felipe Contreras felipe.contre...@gmail.com --- transport-helper.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/transport-helper.c b/transport-helper.c index 835815f..522d791 100644 --- a/transport-helper.c +++ b/transport-helper.c @@ -214,9 +214,8 @@ static struct child_process *get_helper(struct transport *transport) int i; data-refspec_nr = refspec_nr; data-refspecs = parse_fetch_refspec(refspec_nr, refspecs); - for (i = 0; i refspec_nr; i++) { + for (i = 0; i refspec_nr; i++) free((char *)refspecs[i]); - } free(refspecs); } strbuf_release(buf); -- 1.8.3.rc1.553.gac13664 -- 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/4] {fast-export,transport-helper}: style cleanups
Signed-off-by: Felipe Contreras felipe.contre...@gmail.com --- builtin/fast-export.c | 24 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/builtin/fast-export.c b/builtin/fast-export.c index d60d675..8091354 100644 --- a/builtin/fast-export.c +++ b/builtin/fast-export.c @@ -135,7 +135,7 @@ static void export_blob(const unsigned char *sha1) buf = read_sha1_file(sha1, type, size); if (!buf) - die (Could not read blob %s, sha1_to_hex(sha1)); + die(Could not read blob %s, sha1_to_hex(sha1)); if (check_sha1_signature(sha1, buf, size, typename(type)) 0) die(sha1 mismatch in blob %s, sha1_to_hex(sha1)); object = parse_object_buffer(sha1, type, size, buf, eaten); @@ -146,7 +146,7 @@ static void export_blob(const unsigned char *sha1) printf(blob\nmark :%PRIu32\ndata %lu\n, last_idnum, size); if (size fwrite(buf, size, 1, stdout) != 1) - die_errno (Could not write blob '%s', sha1_to_hex(sha1)); + die_errno(Could not write blob '%s', sha1_to_hex(sha1)); printf(\n); show_progress(); @@ -289,13 +289,13 @@ static void handle_commit(struct commit *commit, struct rev_info *rev) parse_commit(commit); author = strstr(commit-buffer, \nauthor ); if (!author) - die (Could not find author in commit %s, + die(Could not find author in commit %s, sha1_to_hex(commit-object.sha1)); author++; author_end = strchrnul(author, '\n'); committer = strstr(author_end, \ncommitter ); if (!committer) - die (Could not find committer in commit %s, + die(Could not find committer in commit %s, sha1_to_hex(commit-object.sha1)); committer++; committer_end = strchrnul(committer, '\n'); @@ -395,7 +395,7 @@ static void handle_tag(const char *name, struct tag *tag) buf = read_sha1_file(tag-object.sha1, type, size); if (!buf) - die (Could not read tag %s, sha1_to_hex(tag-object.sha1)); + die(Could not read tag %s, sha1_to_hex(tag-object.sha1)); message = memmem(buf, size, \n\n, 2); if (message) { message += 2; @@ -421,11 +421,11 @@ static void handle_tag(const char *name, struct tag *tag) if (signature) switch(signed_tag_mode) { case ABORT: - die (Encountered signed tag %s; use + die(Encountered signed tag %s; use --signed-tags=mode to handle it., sha1_to_hex(tag-object.sha1)); case WARN: - warning (Exporting signed tag %s, + warning(Exporting signed tag %s, sha1_to_hex(tag-object.sha1)); /* fallthru */ case VERBATIM: @@ -446,7 +446,7 @@ static void handle_tag(const char *name, struct tag *tag) if (!tagged_mark) { switch(tag_of_filtered_mode) { case ABORT: - die (Tag %s tags unexported object; use + die(Tag %s tags unexported object; use --tag-of-filtered-object=mode to handle it., sha1_to_hex(tag-object.sha1)); case DROP: @@ -454,7 +454,7 @@ static void handle_tag(const char *name, struct tag *tag) return; case REWRITE: if (tagged-type != OBJ_COMMIT) { - die (Tag %s tags unexported %s!, + die(Tag %s tags unexported %s!, sha1_to_hex(tag-object.sha1), typename(tagged-type)); } @@ -467,7 +467,7 @@ static void handle_tag(const char *name, struct tag *tag) if (!(p-object.flags TREESAME)) break; if (!p-parents) - die (Can't find replacement commit for tag %s\n, + die(Can't find replacement commit for tag %s\n, sha1_to_hex(tag-object.sha1)); p = p-parents-item; } @@ -677,7 +677,7 @@ int cmd_fast_export(int argc, const char **argv, const char *prefix) }; if (argc == 1) - usage_with_options (fast_export_usage, options); + usage_with_options(fast_export_usage, options); /* we handle encodings */ git_config(git_default_config, NULL); @@ -689,7
Re: [PATCH] git-svn: added an --include-path flag
Paul Walmsley pjwh...@gmail.com wrote: The SVN::Fetcher module is now able to filter for inclusion as well as exclusion (as used by --ignore-path). Also added tests, documentation changes and git completion script. If you have an SVN repository with many top level directories and you only want a git-svn clone of some of them then using --ignore-path is difficult as it requires a very long regexp. In this case it's much easier to filter for inclusion. Signed-off-by: Paul Walmsley pjwh...@gmail.com Thanks, signed-off and applied, will push. -- 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/3] mingw.h: Define only if necessary
Since the latest version of MSVC EWOULDBLOCK, EAFNOSUPPORT and ECONNABORTED are defined in errno.h. When used with MSVC mingw.h is included from msvc.h and causes warnings about redefinitions. Signed-off-by: Sven Strickroth em...@cs-ware.de --- compat/mingw.h | 6 ++ 1 file changed, 6 insertions(+) diff --git a/compat/mingw.h b/compat/mingw.h index 685cd2c..c424333 100644 --- a/compat/mingw.h +++ b/compat/mingw.h @@ -32,7 +32,9 @@ typedef int socklen_t; #define WEXITSTATUS(x) ((x) 0xff) #define WTERMSIG(x) SIGTERM +#ifndef EWOULDBLOCK #define EWOULDBLOCK EAGAIN +#endif #define SHUT_WR SD_SEND #define SIGHUP 1 @@ -46,8 +48,12 @@ typedef int socklen_t; #define F_SETFD 2 #define FD_CLOEXEC 0x1 +#ifndef EAFNOSUPPORT #define EAFNOSUPPORT WSAEAFNOSUPPORT +#endif +#ifndef ECONNABORTED #define ECONNABORTED WSAECONNABORTED +#endif struct passwd { char *pw_name; -- Best regards, Sven Strickroth PGP key id F5A9D4C4 @ any key-server -- 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/3] poll.h lies in the same folder, so use normal quotes for include
Some compilers, like Visual C++ complain when is used instead of double quotes for non system includes. Signed-off-by: Sven Strickroth em...@cs-ware.de --- compat/poll/poll.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compat/poll/poll.c b/compat/poll/poll.c index 7d226ec..b85386a 100644 --- a/compat/poll/poll.c +++ b/compat/poll/poll.c @@ -31,7 +31,7 @@ #include sys/types.h /* Specification. */ -#include poll.h +#include poll.h #include errno.h #include limits.h -- Best regards, Sven Strickroth PGP key id F5A9D4C4 @ any key-server -- 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/3] Initialize variables with values
With MSVC initializing a variable with int a=a causes a warning about using an uninitialized value. Signed-off-by: Sven Strickroth em...@cs-ware.de --- builtin/rev-list.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/builtin/rev-list.c b/builtin/rev-list.c index 67701be..13afacd 100644 --- a/builtin/rev-list.c +++ b/builtin/rev-list.c @@ -338,7 +338,7 @@ int cmd_rev_list(int argc, const char **argv, const char *prefix) mark_edges_uninteresting(revs.commits, revs, show_edge); if (bisect_list) { - int reaches = reaches, all = all; + int reaches = 0, all = 0; revs.commits = find_bisection(revs.commits, reaches, all, bisect_find_all); -- Best regards, Sven Strickroth PGP key id F5A9D4C4 @ any key-server -- 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/3] fast-export: improve argument parsing
We don't want to pass arguments specific to fast-export to setup_revisions. Signed-off-by: Felipe Contreras felipe.contre...@gmail.com --- builtin/fast-export.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/builtin/fast-export.c b/builtin/fast-export.c index d60d675..6e46057 100644 --- a/builtin/fast-export.c +++ b/builtin/fast-export.c @@ -686,8 +686,9 @@ int cmd_fast_export(int argc, const char **argv, const char *prefix) revs.topo_order = 1; revs.show_source = 1; revs.rewrite_parents = 1; + argc = parse_options(argc, argv, prefix, options, fast_export_usage, + PARSE_OPT_KEEP_ARGV0 | PARSE_OPT_KEEP_UNKNOWN); argc = setup_revisions(argc, argv, revs, NULL); - argc = parse_options(argc, argv, prefix, options, fast_export_usage, 0); if (argc 1) usage_with_options (fast_export_usage, options); -- 1.8.3.rc1.553.gac13664 -- 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/3] fast-export: add new --refspec option
So that we can covert the exported ref names. Signed-off-by: Felipe Contreras felipe.contre...@gmail.com --- Documentation/git-fast-export.txt | 4 builtin/fast-export.c | 30 ++ t/t9350-fast-export.sh| 7 +++ 3 files changed, 41 insertions(+) diff --git a/Documentation/git-fast-export.txt b/Documentation/git-fast-export.txt index 03fc8c3..d1985d3 100644 --- a/Documentation/git-fast-export.txt +++ b/Documentation/git-fast-export.txt @@ -105,6 +105,10 @@ marks the same across runs. in the commit (as opposed to just listing the files which are different from the commit's first parent). +--refspec:: + Apply the specified refspec to each ref exported. Multiple of them can + be specified. + [git-rev-list-args...]:: A list of arguments, acceptable to 'git rev-parse' and 'git rev-list', that specifies the specific objects and references diff --git a/builtin/fast-export.c b/builtin/fast-export.c index 6e46057..0097103 100644 --- a/builtin/fast-export.c +++ b/builtin/fast-export.c @@ -17,6 +17,7 @@ #include utf8.h #include parse-options.h #include quote.h +#include remote.h static const char *fast_export_usage[] = { N_(git fast-export [rev-list-opts]), @@ -30,6 +31,8 @@ static int fake_missing_tagger; static int use_done_feature; static int no_data; static int full_tree; +static struct refspec *refspecs; +static int refspecs_nr; static int parse_opt_signed_tag_mode(const struct option *opt, const char *arg, int unset) @@ -502,6 +505,15 @@ static void get_tags_and_duplicates(struct rev_cmdline_info *info, if (dwim_ref(e-name, strlen(e-name), sha1, full_name) != 1) continue; + if (refspecs) { + char *private; + private = apply_refspecs(refspecs, refspecs_nr, full_name); + if (private) { + free(full_name); + full_name = private; + } + } + switch (e-item-type) { case OBJ_COMMIT: commit = (struct commit *)e-item; @@ -653,6 +665,7 @@ int cmd_fast_export(int argc, const char **argv, const char *prefix) struct commit *commit; char *export_filename = NULL, *import_filename = NULL; uint32_t lastimportid; + struct string_list refspecs_list; struct option options[] = { OPT_INTEGER(0, progress, progress, N_(show progress after n objects)), @@ -673,6 +686,8 @@ int cmd_fast_export(int argc, const char **argv, const char *prefix) OPT_BOOLEAN(0, use-done-feature, use_done_feature, N_(Use the done feature to terminate the stream)), OPT_BOOL(0, no-data, no_data, N_(Skip output of blob data)), + OPT_STRING_LIST(0, refspec, refspecs_list, N_(refspec), +N_(Apply refspec to exported refs)), OPT_END() }; @@ -692,6 +707,19 @@ int cmd_fast_export(int argc, const char **argv, const char *prefix) if (argc 1) usage_with_options (fast_export_usage, options); + if (refspecs_list.nr) { + const char *refspecs_str[refspecs_list.nr]; + int i; + + for (i = 0; i refspecs_list.nr; i++) + refspecs_str[i] = refspecs_list.items[i].string; + + refspecs_nr = refspecs_list.nr; + refspecs = parse_fetch_refspec(refspecs_nr, refspecs_str); + + string_list_clear(refspecs_list, 1); + } + if (use_done_feature) printf(feature done\n); @@ -726,5 +754,7 @@ int cmd_fast_export(int argc, const char **argv, const char *prefix) if (use_done_feature) printf(done\n); + free_refspec(refspecs_nr, refspecs); + return 0; } diff --git a/t/t9350-fast-export.sh b/t/t9350-fast-export.sh index 2471bc6..ef2d76e 100755 --- a/t/t9350-fast-export.sh +++ b/t/t9350-fast-export.sh @@ -505,4 +505,11 @@ test_expect_success 'refs are updated even if no commits need to be exported' ' test_cmp expected actual ' +test_expect_success 'use refspec' ' + git fast-export --refspec refs/heads/master:refs/heads/foobar master | \ + grep ^commit | sort | uniq actual + echo commit refs/heads/foobar expected + test_cmp expected actual +' + test_done -- 1.8.3.rc1.553.gac13664 -- 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/3] transport-helper: add support for old:new refspec
By using fast-export's new --refspec option. Signed-off-by: Felipe Contreras felipe.contre...@gmail.com --- t/t5801-remote-helpers.sh | 2 +- transport-helper.c| 14 -- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/t/t5801-remote-helpers.sh b/t/t5801-remote-helpers.sh index dbb02e2..d15f794 100755 --- a/t/t5801-remote-helpers.sh +++ b/t/t5801-remote-helpers.sh @@ -92,7 +92,7 @@ test_expect_success 'push new branch by name' ' compare_refs local HEAD server refs/heads/new-name ' -test_expect_failure 'push new branch with old:new refspec' ' +test_expect_success 'push new branch with old:new refspec' ' (cd local git push origin new-name:new-refspec ) diff --git a/transport-helper.c b/transport-helper.c index 835815f..b1fdd39 100644 --- a/transport-helper.c +++ b/transport-helper.c @@ -787,7 +787,7 @@ static int push_refs_with_export(struct transport *transport, struct ref *ref; struct child_process *helper, exporter; struct helper_data *data = transport-data; - struct string_list revlist_args = STRING_LIST_INIT_NODUP; + struct string_list revlist_args = STRING_LIST_INIT_DUP; struct strbuf buf = STRBUF_INIT; helper = get_helper(transport); @@ -814,14 +814,24 @@ static int push_refs_with_export(struct transport *transport, die(remote-helpers do not support ref deletion); } - if (ref-peer_ref) + if (ref-peer_ref) { + if (strcmp(ref-name, ref-peer_ref-name)) { + struct strbuf buf = STRBUF_INIT; + strbuf_addf(buf, %s:%s, ref-peer_ref-name, ref-name); + string_list_append(revlist_args, --refspec); + string_list_append(revlist_args, buf.buf); + strbuf_release(buf); + } string_list_append(revlist_args, ref-peer_ref-name); + } } if (get_exporter(transport, exporter, revlist_args)) die(Couldn't run fast-export); + string_list_clear(revlist_args, 1); + if (finish_command(exporter)) die(Error while running fast-export); push_update_refs_status(data, remote_refs); -- 1.8.3.rc1.553.gac13664 -- 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 1/5] msvc: Fix compilation errors caused by poll.h emulation
Am 31.01.2013 19:28 schrieb Ramsay Jones: Commit 0f77dea9 (mingw: move poll out of sys-folder, 24-10-2011), along with other commits in the 'ef/mingw-upload-archive' branch (see commit 7406aa20), effectively reintroduced the same problem addressed by commit 56fb3ddc (msvc: Fix compilation errors in compat/win32/sys/poll.c, 04-12-2010). In order to fix the compilation errors, we use the same solution adopted in that earlier commit. In particular, we set _WIN32_WINNT to 0x0502 (which would target Windows Server 2003) prior to including the winsock2.h header file. This change causes problems compiling with MSVC2012 for me. If I don't define NO_SYS_POLL_H git-compat-util.h now tries to include sys/poll.h which does not exist for MSVC and if I define NO_SYS_POLL_H git-compat-util.h now tries to include poll.h which also doesn't exist for MSVC. Including compat/poll into the includes path causes redefinition errors. How have you tested this? I think the check in git-compat-util.h has to be extended to only include any poll.h if _MSC_VER is defined. -- Best regards, Sven Strickroth PGP key id F5A9D4C4 @ any key-server -- 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