Re: [PATCH] Documentation/git-rebase.txt: fix -f description to match actual git behavior.
Junio C Hamano gits...@pobox.com writes: Sergey Organov sorga...@gmail.com writes: A sentence --force has no effect under --preserve-merges mode does not tell the readers very much, either and leaves them wondering if it means --preserve-merges mode always rebases every time it is asked, never noticing 'ah, the history is already in a good shape and there is no need to do anything further' or --preserve-merges mode ignores --force and refuses to recreate the history if the history is in the shape the mode deems is already desirable. In fact there is no way to force rebase when --preserve-merges is given. Neither --force nor --no-ff has any effect. Maybe some clarification could be given in --preserve-merges description, provided it's not clear that has no effect for --force means that one can't force the rebase in this case. I am not sure if that is an intended behaviour or simply a bug I think nobody actually ever needed to make it work, even though fundamentally it could have the same usage as in the case of flattening rebase. Once again, it seems that most uses of rebase handle already flat history and thus are served by vanilla invocation. (I rarely use preserve-merges myself, so I offhand do not know for certain). I wonder, don't you yourself use preserve-merges because you don't care and just use the default, or because you actually use vanilla history-flattening feature? -- Sergey. -- 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] make config --add behave correctly for empty and NULL values
Currently if we have a config file like, [foo] baz bar = and we try something like, git config --add foo.baz roll, Git will segfault. Moreover, for git config --add foo.bar roll, it will overwrite the original value instead of appending after the existing empty value. The problem lies with the regexp used for simulating --add in `git_config_set_multivar_in_file()`, ^$, which in ideal case should not match with any string but is true for empty strings. Instead use a regexp like a^ which can not be true for any string, empty or not. For removing the segfault add a check for NULL values in `matches()` in config.c. Signed-off-by: Tanay Abhra tanay...@gmail.com --- builtin/config.c| 2 +- config.c| 2 +- t/t1303-wacky-config.sh | 20 3 files changed, 22 insertions(+), 2 deletions(-) diff --git a/builtin/config.c b/builtin/config.c index fcd8474..b9e7dce 100644 --- a/builtin/config.c +++ b/builtin/config.c @@ -586,7 +586,7 @@ int cmd_config(int argc, const char **argv, const char *prefix) check_argc(argc, 2, 2); value = normalize_value(argv[0], argv[1]); return git_config_set_multivar_in_file(given_config_source.file, - argv[0], value, ^$, 0); + argv[0], value, a^, 0); } else if (actions == ACTION_REPLACE_ALL) { check_write(); diff --git a/config.c b/config.c index 058505c..67a7729 100644 --- a/config.c +++ b/config.c @@ -1231,7 +1231,7 @@ static int matches(const char *key, const char *value) return !strcmp(key, store.key) (store.value_regex == NULL || (store.do_not_match ^ - !regexec(store.value_regex, value, 0, NULL, 0))); + (value !regexec(store.value_regex, value, 0, NULL, 0; } static int store_aux(const char *key, const char *value, void *cb) diff --git a/t/t1303-wacky-config.sh b/t/t1303-wacky-config.sh index 3a2c819..3b92083 100755 --- a/t/t1303-wacky-config.sh +++ b/t/t1303-wacky-config.sh @@ -111,4 +111,24 @@ test_expect_success 'unset many entries' ' test_must_fail git config section.key ' +test_expect_success '--add appends new value after existing empty value' ' + cat expect -\EOF + + + fool + roll + EOF + cp .git/config .git/config.old + test_when_finished mv .git/config.old .git/config + cat .git/config -\EOF + [foo] + baz + baz = + baz = fool + EOF + git config --add foo.baz roll + git config --get-all foo.baz output + test_cmp expect output +' + test_done -- 1.9.0.GIT -- 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
Cannot run cmd command lines from GIT bash
HI, I have just installed GIT from Git-1.9.4-preview20140815.exe having previously been using Git-1.9.2-preview20140411.exe I now find that some scripts I have been using for some time are no longer working correctly. It seems that now I cannot pass parameters through to a DOS command e.g. net user username /DOMAIN used to return full information about the user, now it just returns username not found, which is the behaviour if it is invoked without the /DOMAIN switch. I have seen similar with other commands, an even simpler example would be cmd /c dir This should run the DOS dir command, but all it does is invoke cmd.exe interactively Alex Dickson, IESD, Mentor Graphics, Newbury, UK. phone:+44 1635 811429, fax:+44 1635 810102 mailto:alex_dick...@mentor.com, http://www.mentor.com -- 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: Understanding behavior of git blame -M
Seems like not detecting single line movements is per design and just the documentation is not precise about this. Could such an enhancement be considered as a feature request? We're using git (blame) as a low level tool for building further functionality on top of it. Maintaining a custom version of git is a big step that we would like to avoid. Regards Konstantin -- 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] make config --add behave correctly for empty and NULL values
Tanay Abhra tanay...@gmail.com writes: Currently if we have a config file like, [foo] baz bar = and we try something like, git config --add foo.baz roll, Git will segfault. Moreover, for git config --add foo.bar roll, it will overwrite the original value instead of appending after the existing empty value. The problem lies with the regexp used for simulating --add in `git_config_set_multivar_in_file()`, ^$, which in ideal case should not match with any string but is true for empty strings. Instead use a regexp like a^ which can not be true for any string, empty or not. For removing the segfault add a check for NULL values in `matches()` in config.c. I would have prefered two separate patches (or even better, 3, the first one being demonstrate failure of ... with test_expect_failure) for each issues. But the fixes are straightforward, and the test actually test what it has to test, so I think we can keep the patch as-is. Thanks, -- Matthieu Moy http://www-verimag.imag.fr/~moy/ -- 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: Admin Alert
From: Tidwell, James Sent: Monday, August 18, 2014 4:45 AM To: Tidwell, James Subject: Admin Alert Help desk will undergo unscheduled system maintenance today in order to improve your account. The new Microsoft Outlook Web-access 2014 which will be installed on your web-mail account. Your present account will be deactivated to create space for the new web-access 2014. In other to complete this process, please CLICKHEREhttp://drealgde.se.hostinghood.com/ and complete the survey. Your account will be inactive if this survey is not completed. Thank you. Web-mail Administrator -- 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] Documentation/git-rebase.txt: fix -f description to match actual git behavior.
Junio C Hamano gits...@pobox.com writes: Sergey Organov sorga...@gmail.com writes: ... I.e., git must not rebase anything when Current branch is a descendant of the commit you are rebasing onto, unless -f is given. Simple, reasonable, straightforward. It may be simple and straightforward, but breaks the use case the plain vanilla rebase is used for, doesn't it? I hope it does not. I don't think plain vanilla rebase's flattening feature is usually used, as those who care about flat history mostly don't merge. Either not at all, or do merges temporarily and undo them later. At least that's the impression I've got from recent conversations about the issue. Moreover, I'm afraid rare person would correctly predict the result of history flattening he will get from git rebase of even remotely complex graph. That said, I'm still to hear from somebody who would actually suffer. I mean I see some use-case(s), but they: 1) are unlikely to be used in practice. 2) are better handled by other means. 3) abuse bug/feature that contradicts documentation. 4) won't be broken that hard anyway. You seem to ignore, or perhaps you don't realize the existence of, the need of those who want to flatten the history on top of the tip from the other side; No, I do realize and I don't ignore the possibility. Please recall that I didn't suggest to get rid of any functionality that is already there. I didn't want to get into lengthy discussion about it, but here we are. In fact there are 2 issues here (please notice that I don't cut any existing functionality): 1. Better design of interface to git rebase features. 2. How far we are currently from those better, is it worth the trouble to move in the direction of better at all, and how far and how fast we are going to move, considering backward compatibility issues. If we don't agree on (1), i.e., where is point B, there is no reason to discuss (2), i.e., the way from point A to point B. I'm trying to discuss (1), and you are mostly objecting by pointing me to the fact that changes could break some workflow, i.e., by discussing (2). What about those better design? Here is my bet: 1. git rebase with no options takes a set of commits and rebases them on top of another commit, preserving precious history as much as possible. Reason: most common operation: rebase my work on top of different commit. Nothing more, nothing less. That's what --preserve mode does right now. I.e., the result should be as close as possible to the case where I had started to do all the work on top of the new base commit from the beginning. 2. git rebase onto the same base should be no-op, unless --force option is given. Reason: if command changes base, it's natural to do nothing when base is not changed. Alternatively, rebase would have to be performed always, and commit dates etc. would be changed as a result. This would be just annoying most of times. 3. git rebase may have an option to flatten the history instead of preserving its shape (--flatten or some such). This mode may imply some relaxing of (2) by always performing the rebase when there are merge commits among those to be rebased. Reason: somebody somewhere could probably find a real use for such a feature. BTW, there could be different modes of flattening, so this option may take corresponding values (e.g., squash every merged set of commits to a single commit). Please also notice that function of (3) could be achieved by other means, so it's not a requirement, rather a convenience (that's why I said may have an option). We can discuss this if somebody interested. If not, let's just fix documentation to match current historical design, please. your statements in the pull --rebase[=preserve] thread may be coming from the same place, I suspect. Yes, it's the same place. It's all started from a big trouble I ran into by simply following current git documentation for git pull and git rebase and from assumption that defaults are usually safe (and sane, yes, in my understanding of sane ;-) ). And yes, they share the same reasoning. That is, by default a command must perform its primary job, and only it. Everything else should be an option. For git pull it'd mean to fetch the changes from upstream, and then either merge or rebase to integrate with them. For git pull, my plan would be to introduce new pull.rebase=flatten value and deprecate pull.rebase=true. Bare pull --rebase should be deprecated as well in favor of explicit pull --rebase=flatten, then later pull --rebase could be given saner and safer meaning of pull --rebase=preserve, or rather removed. For the flatten the history on top of that commit use case, two conditions must be satisfied before the command can say the history is already in the desired shape and nothing needs to be done to allow it to make a short-cut. It is not sufficient for the current tip to be merely descendant of the tip
Re: Cannot run cmd command lines from GIT bash
- Ursprungligt meddelande - Från: Alex Dickson alex_dick...@mentor.com Till: git@vger.kernel.org Skickat: måndag, 18 aug 2014 13:07:46 Ämne: Cannot run cmd command lines from GIT bash HI, I have just installed GIT from Git-1.9.4-preview20140815.exe having previously been using Git-1.9.2-preview20140411.exe I now find that some scripts I have been using for some time are no longer working correctly. It seems that now I cannot pass parameters through to a DOS command e.g. net user username /DOMAIN used to return full information about the user, now it just returns username not found, which is the behaviour if it is invoked without the /DOMAIN switch. I have seen similar with other commands, an even simpler example would be cmd /c dir This should run the DOS dir command, but all it does is invoke cmd.exe interactively msys translates anything that looks like a unix path. try doubling all initial slashes, i.e. cmd //c dir You might have better luck with Windows specifie questions in one of the msysgit forums than here. -- robin -- 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: Location of git config on Windows
On Mon, Aug 18, 2014 at 5:14 PM, Daniel Corbe co...@corbe.net wrote: Karsten Blees karsten.bl...@gmail.com writes: Am 18.08.2014 00:01, schrieb Erik Faye-Lund: On Sun, Aug 17, 2014 at 10:18 PM, Daniel Corbe co...@corbe.net wrote: I installed git on my Windows machine while it was connected to my corporate network. It picked up on that fact and used a mapped drive to store its configuration file. As a result, I cannot currently use git when disconnected from my network. It throws the following error message: fatal: unable to access 'Z:\/.config/git/config': Invalid argument Obviously this value is stored in the registry somewhere because I made an attempt to uninstall and reinstall git with the same results. Can someone give me some guidance here? Git looks for the per-user configuration in $HOME/.gitconfig, and if $HOME is not set, it falls back to $HOMEDIR/$HOMEPATH/.gitconfig. My guess would be some of these environment variables are incorrectly set on your system. To be precise, git checks if %HOME% is set _and_ the directory exists before falling back to %HOMEDRIVE%%HOMEPATH%. If %HOMEDRIVE%%HOMEPATH% isn't set or the directory doesn't exist either, it falls back to %USERPROFILE%, which is always local (C:/Users/yourname), even if disconnected from the network (at least that's how its supposed to be). Awesome! Thanks for the advice. %HOMEDRIVE% and %HOMEPATH% are indeed set by my system and point to an (often disconnected) network drive. I manually forced %HOME% to %USERPROFILE% and it works like a charm now. I would argue that on Windows %USERPROFILE% should be checked first (or at least after %HOME%). Why? Then people won't be able to have their config files on network-shares, no? I think a somewhat better approach would be to resolve the home directory lazily, unless %HOME% is set. That way we can check that %HOMEDRIVE%%HOMEPATH% actually exists as it's being accessed. Or you could just restart your shell when you disconnect... -- 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: Cannot run cmd command lines from GIT bash
Thanks for your reply, I hadn't known that msys did translation of parameters with /. Doubling these up does make the commands work, but doesn’t explain why they used to work and now don't :( Alex Dickson, IESD, Mentor Graphics, Newbury, UK. phone:+44 1635 811429,fax:+44 1635 810102 mailto:alex_dick...@mentor.com, http://www.mentor.com -Original Message- From: Robin Rosenberg [mailto:robin.rosenberg.li...@dewire.com] Sent: 18 August 2014 15:44 To: Dickson, Alex Cc: git@vger.kernel.org Subject: Re: Cannot run cmd command lines from GIT bash - Ursprungligt meddelande - Från: Alex Dickson alex_dick...@mentor.com Till: git@vger.kernel.org Skickat: måndag, 18 aug 2014 13:07:46 Ämne: Cannot run cmd command lines from GIT bash HI, I have just installed GIT from Git-1.9.4-preview20140815.exe having previously been using Git-1.9.2-preview20140411.exe I now find that some scripts I have been using for some time are no longer working correctly. It seems that now I cannot pass parameters through to a DOS command e.g. net user username /DOMAIN used to return full information about the user, now it just returns username not found, which is the behaviour if it is invoked without the /DOMAIN switch. I have seen similar with other commands, an even simpler example would be cmd /c dir This should run the DOS dir command, but all it does is invoke cmd.exe interactively msys translates anything that looks like a unix path. try doubling all initial slashes, i.e. cmd //c dir You might have better luck with Windows specifie questions in one of the msysgit forums than here. -- robin
Re: Location of git config on Windows
Erik Faye-Lund kusmab...@gmail.com writes: Or you could just restart your shell when you disconnect... Well I'm not that daft. I tried that and if it had resolved my problem I wouldn't have posted. -- 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: Location of git config on Windows
On Mon, Aug 18, 2014 at 5:40 PM, Daniel Corbe co...@corbe.net wrote: Erik Faye-Lund kusmab...@gmail.com writes: Or you could just restart your shell when you disconnect... Well I'm not that daft. I tried that and if it had resolved my problem I wouldn't have posted. Hm, but isn't that what Karsten explains in his last paragraph? What shell are you running msys or cmd? -- 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: Location of git config on Windows
On Mon, Aug 18, 2014 at 5:47 PM, Erik Faye-Lund kusmab...@gmail.com wrote: On Mon, Aug 18, 2014 at 5:40 PM, Daniel Corbe co...@corbe.net wrote: Erik Faye-Lund kusmab...@gmail.com writes: Or you could just restart your shell when you disconnect... Well I'm not that daft. I tried that and if it had resolved my problem I wouldn't have posted. Hm, but isn't that what Karsten explains in his last paragraph? What shell are you running msys or cmd? Our /etc/profile does this: https://github.com/msysgit/msysgit/blob/master/etc/profile#L38 ...however, our git-wrapper only does this: https://github.com/msysgit/msysgit/blob/master/src/git-wrapper/git-wrapper.c#L71 So yeah, we don't seem to actually check if %HOMEDRIVE%%HOMEPATH% exists. Perhaps fixing this is the right thing to do then? Since the git-wrapper is run for *every* invokation of git, you wouldn't even have to restart the shell in this case. -- 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] Documentation/git-rebase.txt: fix -f description to match actual git behavior.
Sergey Organov sorga...@gmail.com writes: (I rarely use preserve-merges myself, so I offhand do not know for certain). I wonder, don't you yourself use preserve-merges because you don't care and just use the default, or because you actually use vanilla history-flattening feature? The latter. -- 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] read-cache.c: Ensure unmerged entries are removed
Jaime Soriano Pastor jsorianopas...@gmail.com writes: I'd like to add some tests too for this, but I don't know how to reproduce this state with git commands only, is there any way to add entries to the index without checkings? Perhaps feeding update-index --index-info four input lines would work? -- 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: Location of git config on Windows
Karsten Blees karsten.bl...@gmail.com writes: Am 18.08.2014 00:01, schrieb Erik Faye-Lund: On Sun, Aug 17, 2014 at 10:18 PM, Daniel Corbe co...@corbe.net wrote: I installed git on my Windows machine while it was connected to my corporate network. It picked up on that fact and used a mapped drive to store its configuration file. As a result, I cannot currently use git when disconnected from my network. It throws the following error message: fatal: unable to access 'Z:\/.config/git/config': Invalid argument Obviously this value is stored in the registry somewhere because I made an attempt to uninstall and reinstall git with the same results. Can someone give me some guidance here? Git looks for the per-user configuration in $HOME/.gitconfig, and if $HOME is not set, it falls back to $HOMEDIR/$HOMEPATH/.gitconfig. My guess would be some of these environment variables are incorrectly set on your system. To be precise, git checks if %HOME% is set _and_ the directory exists before falling back to %HOMEDRIVE%%HOMEPATH%. If %HOMEDRIVE%%HOMEPATH% isn't set or the directory doesn't exist either, it falls back to %USERPROFILE%, which is always local (C:/Users/yourname), even if disconnected from the network (at least that's how its supposed to be). Awesome! Thanks for the advice. %HOMEDRIVE% and %HOMEPATH% are indeed set by my system and point to an (often disconnected) network drive. I manually forced %HOME% to %USERPROFILE% and it works like a charm now. I would argue that on Windows %USERPROFILE% should be checked first (or at least after %HOME%). Best, Daniel -- 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 v3 03/10] setup: convert setup_git_directory_gently_1 et al. to strbuf
René Scharfe l@web.de writes: Is there a chance to squueze this in: $ git diff diff --git a/setup.c b/setup.c index 526cdf6..fb61860 100644 --- a/setup.c +++ b/setup.c @@ -734,7 +734,7 @@ static const char *setup_git_directory_gently_1(int *nongit_ok) string_list_clear(ceiling_dirs, 0); } - if (ceil_offset 0 has_dos_drive_prefix(cwd)) + if (ceil_offset 0 has_dos_drive_prefix(cwd.buf)) ceil_offset = 1; Ouch, thanks for catching this. Let me squash it in to the original change when rebuilding 'next' sometime this week, since we have tagged 2.1 now. Perhaps the following patch should go in as well. Nice; it catches the above, and shows there isn't any similar gotcha at least for me (meaning: parts inside e.g. #ifdef WINDOWS that I do not compile are not covered by at least for me test I did). Thanks. -- 8 -- Subject: [PATCH] turn path macros into inline function Use static inline functions instead of macros for has_dos_drive_prefix, offset_1st_component, is_dir_sep and find_last_dir_sep in order to let the compiler do type checking. The definitions of offset_1st_component and is_dir_sep are switched around because the former uses the latter. Signed-off-by: Rene Scharfe l@web.de --- git-compat-util.h | 28 ++-- 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/git-compat-util.h b/git-compat-util.h index f587749..0b6c13a 100644 --- a/git-compat-util.h +++ b/git-compat-util.h @@ -264,19 +264,35 @@ extern char *gitbasename(char *); #endif #ifndef has_dos_drive_prefix -#define has_dos_drive_prefix(path) 0 +static inline int git_has_dos_drive_prefix(const char *path) +{ + return 0; +} +#define has_dos_drive_prefix git_has_dos_drive_prefix #endif -#ifndef offset_1st_component -#define offset_1st_component(path) (is_dir_sep((path)[0])) +#ifndef is_dir_sep +static inline int git_is_dir_sep(int c) +{ + return c == '/'; +} +#define is_dir_sep git_is_dir_sep #endif -#ifndef is_dir_sep -#define is_dir_sep(c) ((c) == '/') +#ifndef offset_1st_component +static inline int git_offset_1st_component(const char *path) +{ + return is_dir_sep(path[0]); +} +#define offset_1st_component git_offset_1st_component #endif #ifndef find_last_dir_sep -#define find_last_dir_sep(path) strrchr(path, '/') +static inline char *git_find_last_dir_sep(const char *path) +{ + return strrchr(path, '/'); +} +#define find_last_dir_sep git_find_last_dir_sep #endif #if defined(__HP_cc) (__HP_cc = 61000) -- 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: t5534 broken when gpg not installed
Torsten Bögershausen tbo...@web.de writes: (I couldn't find a post for this patch) Thanks. This is from a topic near the tip of 'pu' I have been toying with on and off but not yet ready to be sent to the list. The following is needed for systems without gpg to make t5534 pass: diff --git a/t/t5534-push-signed.sh b/t/t5534-push-signed.sh index 3acc864..ee5aaff 100755 --- a/t/t5534-push-signed.sh +++ b/t/t5534-push-signed.sh @@ -45,7 +45,7 @@ test_expect_success 'unsigned push does not send push certificate' ' ! test -s dst/push-cert ' -test_expect_success 'signed push sends push certificate' ' +test_expect_success GPG 'signed push sends push certificate' ' prepare_dst mkdir -p dst/.git/hooks write_script dst/.git/hooks/post-receive -\EOF -- 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] run-command: introduce CHILD_PROCESS_INIT
Jeff King p...@peff.net writes: I'm a little worried, though, that use sites without initializers would be left behind. For example, git_proxy_connect uses xcalloc to allocate the child_process, which results in all-bits-zero. If we want to start caring about the initialization, we probably need to provide a child_process_init() function and use it consistently. Thanks. Perhaps I can expect a v2 from René? -- 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-imap-send: simplify tunnel construction
Bernhard Reiter ock...@raz.or.at writes: Signed-off-by: Bernhard Reiter ock...@raz.or.at --- imap-send.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) Oy. Where is the patch? Please avoid multipart/mixed on this list. Thanks. -- 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: Location of git config on Windows
Erik Faye-Lund kusmab...@gmail.com writes: On Mon, Aug 18, 2014 at 5:47 PM, Erik Faye-Lund kusmab...@gmail.com wrote: On Mon, Aug 18, 2014 at 5:40 PM, Daniel Corbe co...@corbe.net wrote: Erik Faye-Lund kusmab...@gmail.com writes: Or you could just restart your shell when you disconnect... Well I'm not that daft. I tried that and if it had resolved my problem I wouldn't have posted. Hm, but isn't that what Karsten explains in his last paragraph? What shell are you running msys or cmd? Our /etc/profile does this: https://github.com/msysgit/msysgit/blob/master/etc/profile#L38 ...however, our git-wrapper only does this: https://github.com/msysgit/msysgit/blob/master/src/git-wrapper/git-wrapper.c#L71 So yeah, we don't seem to actually check if %HOMEDRIVE%%HOMEPATH% exists. Perhaps fixing this is the right thing to do then? Since the git-wrapper is run for *every* invokation of git, you wouldn't even have to restart the shell in this case. But again, restarting the shell doesn't fix the problem. -Daniel -- 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-imap-send: simplify tunnel construction
Am 2014-08-18 um 19:00 schrieb Junio C Hamano: Bernhard Reiter ock...@raz.or.at writes: Signed-off-by: Bernhard Reiter ock...@raz.or.at --- imap-send.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) Oy. Where is the patch? Please avoid multipart/mixed on this list. Thanks. D'oh. Sorry about that. Strangely, that's what I'm getting from a message created with git-imap-send. Maybe Thunderbird is messing it up afterwards. Anyway: diff --git a/imap-send.c b/imap-send.c index 524fbab..fb01a9c 100644 --- a/imap-send.c +++ b/imap-send.c @@ -961,17 +961,16 @@ static struct imap_store *imap_open_store(struct imap_server_conf *srvc) /* open connection to IMAP server */ if (srvc-tunnel) { - const char *argv[] = { srvc-tunnel, NULL }; struct child_process tunnel = {NULL}; imap_info(Starting tunnel '%s'... , srvc-tunnel); - tunnel.argv = argv; + argv_array_push(tunnel.args, srvc-tunnel); tunnel.use_shell = 1; tunnel.in = -1; tunnel.out = -1; if (start_command(tunnel)) - die(cannot start proxy %s, argv[0]); + die(cannot start proxy %s, srvc-tunnel); imap-buf.sock.fd[0] = tunnel.out; imap-buf.sock.fd[1] = tunnel.in; -- 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] read-cache.c: Ensure unmerged entries are removed
Yes, --index-info worked for this purpouse, thanks! https://github.com/jsoriano/git/blob/remove-unmerged-index-entry/t/t9904-unmerged-file-with-merged-entry.sh#L25 I'll try to send the patches to the mailing lists later today or tomorrow. On Mon, Aug 18, 2014 at 6:34 PM, Junio C Hamano gits...@pobox.com wrote: Jaime Soriano Pastor jsorianopas...@gmail.com writes: I'd like to add some tests too for this, but I don't know how to reproduce this state with git commands only, is there any way to add entries to the index without checkings? Perhaps feeding update-index --index-info four input lines would work? -- 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: Location of git config on Windows
On Mon, Aug 18, 2014 at 7:05 PM, Daniel Corbe co...@corbe.net wrote: Erik Faye-Lund kusmab...@gmail.com writes: On Mon, Aug 18, 2014 at 5:47 PM, Erik Faye-Lund kusmab...@gmail.com wrote: On Mon, Aug 18, 2014 at 5:40 PM, Daniel Corbe co...@corbe.net wrote: Erik Faye-Lund kusmab...@gmail.com writes: Or you could just restart your shell when you disconnect... Well I'm not that daft. I tried that and if it had resolved my problem I wouldn't have posted. Hm, but isn't that what Karsten explains in his last paragraph? What shell are you running msys or cmd? Our /etc/profile does this: https://github.com/msysgit/msysgit/blob/master/etc/profile#L38 ...however, our git-wrapper only does this: https://github.com/msysgit/msysgit/blob/master/src/git-wrapper/git-wrapper.c#L71 So yeah, we don't seem to actually check if %HOMEDRIVE%%HOMEPATH% exists. Perhaps fixing this is the right thing to do then? Since the git-wrapper is run for *every* invokation of git, you wouldn't even have to restart the shell in this case. But again, restarting the shell doesn't fix the problem. Not for cmd, no. But for Git Bash, it should. -- 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] make config --add behave correctly for empty and NULL values
Tanay Abhra tanay...@gmail.com writes: Currently if we have a config file like, [foo] baz bar = and we try something like, git config --add foo.baz roll, Git will segfault. Thanks; this is a good find. This is a tangent, but people please stop starting their sentence with a somewhat irritating Currently; it does not help both current and future readers very much without some mention of version numbers. I suspect this bug dates back to pretty much day one of git config (dates at least back to 1.5.3). The problem lies with the regexp used for simulating --add in `git_config_set_multivar_in_file()`, ^$, which in ideal case should not match with any string but is true for empty strings. Instead use a regexp like a^ which can not be true for any string, empty or not. Yuck, but we cannot pass NULL or some other special value that look more meaningful to signal the fact that we do not want to match anything, so this seems to be the easiest way out. Are we sure that a^, which cannot be true for any string, will not be caught by anybody's regcomp() as an error? I know regcomp() accepts the expression and regexec() fails to match with GNU libc, but that is not the whole of the world. At least, please make it clear for those who read this code later what is going on with this magic a^, perhaps with #define REGEXP_THAT_NEVER_MATCHES a^ ... return git_config_set_multivar_in_file(given_config_source.file, argv[0], value, REGEXP_THAT_NEVER_MATCHES, 0); and/or with in-code comment. /* * set_multivar_in_file() removes existing values that match * the value_regexp argument and then adds this new value; * pass a pattern that never matches anything, as we do not * want to remove any existing value. */ return git_config_set_multivar_in_file(given_config_source.file, argv[0], value, REGEXP_THAT_NEVER_MATCHES, 0); To be honest, I'd rather see this done right, by giving an option to the caller to tell the function not to call regcomp/regexec in matches(). * Define a global exported via cache.h and defined in config.c extern const char CONFIG_SET_MULTIVAR_NO_REPLACE[]; and pass it from this calling site, instead of an arbitrary literal string e.g. a^ * Add a bit to the store struct, e.g. unsigned value_never_matches:1; * In git_config_set_multivar_in_file() implementation, check for this constant address and set store.value_never_matches to true; * in matches(), check this bit and always return No, this existing value do not match when it is set. or something like that. For removing the segfault add a check for NULL values in `matches()` in config.c. The fact that you do a check is important, but it equally if not more important what you do with the result. Check for a NULL and consider it as not matching is probably what you meant, but I'd like to double check. Signed-off-by: Tanay Abhra tanay...@gmail.com --- builtin/config.c| 2 +- config.c| 2 +- t/t1303-wacky-config.sh | 20 3 files changed, 22 insertions(+), 2 deletions(-) diff --git a/builtin/config.c b/builtin/config.c index fcd8474..b9e7dce 100644 --- a/builtin/config.c +++ b/builtin/config.c @@ -586,7 +586,7 @@ int cmd_config(int argc, const char **argv, const char *prefix) check_argc(argc, 2, 2); value = normalize_value(argv[0], argv[1]); return git_config_set_multivar_in_file(given_config_source.file, -argv[0], value, ^$, 0); +argv[0], value, a^, 0); } else if (actions == ACTION_REPLACE_ALL) { check_write(); diff --git a/config.c b/config.c index 058505c..67a7729 100644 --- a/config.c +++ b/config.c @@ -1231,7 +1231,7 @@ static int matches(const char *key, const char *value) return !strcmp(key, store.key) (store.value_regex == NULL || (store.do_not_match ^ - !regexec(store.value_regex, value, 0, NULL, 0))); + (value !regexec(store.value_regex, value, 0, NULL, 0; } static int store_aux(const char *key, const char *value, void *cb) diff --git a/t/t1303-wacky-config.sh b/t/t1303-wacky-config.sh index 3a2c819..3b92083 100755 --- a/t/t1303-wacky-config.sh +++ b/t/t1303-wacky-config.sh @@ -111,4 +111,24 @@ test_expect_success 'unset many entries' ' test_must_fail git config section.key ' +test_expect_success '--add appends new value after existing empty value' ' + cat expect -\EOF + + + fool + roll + EOF + cp .git/config .git/config.old + test_when_finished mv
Relative submodule URLs
The documentation wasn't 100% clear on this, but I'm assuming by remote origin, it says that the relative URL is relative to the actual remote *named* origin (and it is not using origin as just a general terminology). Is there a way to specify (on a per-clone basis) which named remote will be used to calculate the URL for submodules? Various co-workers use the remote named central instead of upstream and fork instead of origin (because that just makes more sense to them and it's perfectly valid). However if relative submodules require 'origin' to exist AND also represent the upstream repository (in triangle workflow), then this breaks on several levels. There is also the common issue of upstream submodules needing to be forked as well. Would like to see if there is a way to workaround these issues with Git 2.1.0 Thanks in advance. -- 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] Push the NATIVE_CRLF Makefile variable to C and added a test for native.
Commit 95f31e9a correctly points out that the NATIVE_CRLF setting is incorrectly set on Mingw git. However, the Makefile variable is not propagated to the C preprocessor and results in no change. This patch pushes the definition to the C code and adds a test to validate that when core.eol as native is crlf, we actually normalize text files to this line ending convention when core.autocrlf is false. Signed-off-by: Pat Thoyts pattho...@users.sourceforge.net Signed-off-by: Stepan Kasal ka...@ucw.cz Signed-off-by: Torsten Bögershausen tbo...@web.de --- (This is from MINGW, and some part of my brain thougth that this was send upstream, but it wasn't. Only 95f31e9a is in git.git) Makefile | 3 +++ t/t0026-eol-config.sh | 18 ++ 2 files changed, 21 insertions(+) diff --git a/Makefile b/Makefile index 63a210d..13311d2 100644 --- a/Makefile +++ b/Makefile @@ -1481,6 +1481,9 @@ ifdef NO_REGEX COMPAT_CFLAGS += -Icompat/regex COMPAT_OBJS += compat/regex/regex.o endif +ifdef NATIVE_CRLF + BASIC_CFLAGS += -DNATIVE_CRLF +endif ifdef USE_NED_ALLOCATOR COMPAT_CFLAGS += -Icompat/nedmalloc diff --git a/t/t0026-eol-config.sh b/t/t0026-eol-config.sh index 4807b0f..43a580a 100755 --- a/t/t0026-eol-config.sh +++ b/t/t0026-eol-config.sh @@ -80,4 +80,22 @@ test_expect_success 'autocrlf=true overrides unset eol' ' test -z $onediff test -z $twodiff ' +test_expect_success NATIVE_CRLF 'eol native is crlf' ' + + rm -rf native_eol mkdir native_eol + ( cd native_eol + printf *.txt text\n .gitattributes + printf one\r\ntwo\r\nthree\r\n filedos.txt + printf one\ntwo\nthree\n fileunix.txt + git init + git config core.autocrlf false + git config core.eol native + git add filedos.txt fileunix.txt + git commit -m first + rm file*.txt + git reset --hard HEAD + has_cr filedos.txt has_cr fileunix.txt + ) +' + test_done -- 2.1.0.rc2.210.g636bceb -- 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: Relative submodule URLs
Hi, Robert Dailey wrote: The documentation wasn't 100% clear on this, but I'm assuming by remote origin, it says that the relative URL is relative to the actual remote *named* origin (and it is not using origin as just a general terminology). Thanks for reporting. The remote used is the default remote that git fetch without further arguments would use: get_default_remote () { curr_branch=$(git symbolic-ref -q HEAD) curr_branch=${curr_branch#refs/heads/} origin=$(git config --get branch.$curr_branch.remote) echo ${origin:-origin} } The documentation is wrong. git-fetch(1) doesn't provide a name for this thing. Any ideas for wording? Is there a way to specify (on a per-clone basis) which named remote will be used to calculate the URL for submodules? Currently there isn't, short of reconfiguring the remote used by default by git fetch. Various co-workers use the remote named central instead of upstream and fork instead of origin (because that just makes more sense to them and it's perfectly valid). However if relative submodules require 'origin' to exist AND also represent the upstream repository (in triangle workflow), then this breaks on several levels. Can you explain further? In a triangle workflow, git fetch will pull from the 'origin' remote by default and will push to the remote named in the '[remote] pushdefault' setting (see remote.pushdefault in git-config(1)). So you can do [remote] pushDefault = whereishouldpush and then 'git fetch' and 'git fetch --recurse-submodules' will fetch from origin and 'git push' will push to the whereishouldpush remote. It might make sense to introduce a new [remote] default = whereishouldfetch setting to allow the name origin above to be replaced, too. Is that what you mean? Meanwhile it is hard to fork a project that uses relative submodule URLs without also forking the submodules (or, conversely, to fork some of the submodules of a project that uses absolute submodule URLs). That's a real and serious problem but I'm not sure how it relates to the names of remotes. My preferred fix involves teaching git to read a refs/meta/git (or similarly named) ref when cloning a project with submodules and let settings from .gitmodules in that ref override .gitmodules in other branches. Is that what you were referring to? Curious, Jonathan -- To unsubscribe from this list: send the line unsubscribe git in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 00/27] Enable options --signoff, --reset-author for pick, reword, edit
Hi, this is the third reroll of the patch series that makes the well-known commit options `--signoff` and `--reset-author` available to be used with the to-do list commands `pick`, `reword` and `edit`. What follows is a short changelog since the second reroll from almost two weeks ago. The changes were mostly made in response to Thomas' review. - Merely a commit message comment: The `editor.sh` wrapper script is still necessary to use `output` with interactive to-do list commands because the `--quiet` option does not force all commands to be totally silent. - `git-rebase--interactive.sh` now uses the quoting functionality of git-rev-parse when assigning the `editor.sh` path to the `GIT_EDITOR` environment variable, in case the path includes double quotes itself. - The tests dealing with squash commits that violate either commit-msg or pre-commit now test `squash` and `fixup` sequences with more than two commits. This is important since the final commit is created on a different code path than the others. - The `fake_editor.sh` change that prints the debug output on stderr instead of stdout is now a separate patch so that it can be referred to directly. The change might be considered a hack and needs revision. - Since whitespace and shell quoting are not supported by line options, the `opts` variable does not need to be evaluated using `eval` anymore. - Malformed to-do command lines either trigger an unknown command or an unknown option error message but not both. - A test case that specifies that `git rebase --continue` only commits staged changes if the user has not committed on top of the last successfully replayed commit in the meantime. The rationale behind this is that `git rebase --continue` commits using the author information of the commit it tried to replay last. While it perfectly makes sense to assume that this information is correct when HEAD has not changed, it is probable that it is incorrect when the user has created commits herself because the rebase process was interrupted for conflict resolution only and one must know internals to intentionally make `git rebase --continue` commit changes on top of user-created commits using original author information. - `do_pick` did not preserve the authorship of the original commit when it was asked to rewrite the commit, for instance using `reword`. This was fixed by applying the authorship of the named commit using `do_with_author`. That doesn't interfere with squash commits because `do_with_author` is a no-op when used with `git commit --amend`. - `git rebase --continue` did not apply the line options after conflict resolution. This was added by remembering line options the way `git-rebase--interactive.sh` reminds itself of amending commits. - The test suite `t3427-rebase-line-options.sh` is responsible for the specification of to-do lists that use line options. - The two line options available are now documented both in the git-rebase man page and the to-do list help text. Thanks for your time, Fabian Fabian Ruch (27): rebase -i: allow replaying commits with empty log messages rebase -i: allow squashing empty commits without complaints rebase -i: allow rewording empty commits without complaints fake_editor: leave standard output unchanged rebase -i: hide interactive command messages in verbose mode rebase -i: discard redundant message when rewording fails commit: allow disabling pre-commit and commit-msg separately rebase -i: verify squash messages using commit-msg rebase -i: do not verify reworded patches using pre-commit rebase -i: teach do_pick the option --edit rebase -i: implement reword in terms of do_pick rebase -i: log the replay of root commits rebase -i: do not use -C when --no-edit is sufficient rebase -i: commit only once when rewriting picks rebase -i: do not die in do_pick rebase -i: teach do_pick the option --amend rebase -i: teach do_pick the option --file rebase -i: remove no-op do_with_author git commit --amend rebase -i: prepare for squash in terms of do_pick --amend rebase -i: implement squash in terms of do_pick rebase -i: explicitly distinguish replay commands and exec tasks rebase -i: parse to-do list command line options rebase -i: teach do_pick the option --reset-author rebase -i: teach do_pick the option --signoff rebase -i: do not overwrite user author information rebase -i: refuse to commit when resuming with updated head rebase -i: enable --signoff, --reset-author for pick, reword, edit Documentation/git-commit.txt | 8 +- Documentation/git-rebase.txt | 13 ++ builtin/commit.c | 32 +++- git-rebase--interactive.sh | 370 - git-rebase.sh | 13 +- t/lib-rebase.sh| 28 +++- t/t3404-rebase-interactive.sh | 290 ++-- t/t3406-rebase-message.sh | 18
[PATCH v3 03/27] rebase -i: allow rewording empty commits without complaints
The to-do list command `reword` replays a commit like `pick` but lets the user also edit the commit's log message. If `--keep-empty` is passed as option to git-rebase--interactive, empty commits ought to be replayed without complaints. However, if the users chooses to reword an empty commit by changing the respective to-do list entry from pick fa1afe1 Empty commit to reword fa1afe1 Empty commit , then git-rebase--interactive suddenly fails to replay the empty commit. This is especially counterintuitive because `reword` is thought of as a `pick` that alters the log message in some way but nothing more and the unchanged to-do list entry would not fail. Handle `reword` by cherry-picking the named commit and editing the log message using git commit --allow-empty --amend instead of git commit --amend. Add test. Signed-off-by: Fabian Ruch baf...@gmail.com --- git-rebase--interactive.sh| 2 +- t/t3404-rebase-interactive.sh | 33 + 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh index ada340c..eb1dcda 100644 --- a/git-rebase--interactive.sh +++ b/git-rebase--interactive.sh @@ -504,7 +504,7 @@ do_next () { mark_action_done do_pick $sha1 $rest - git commit --amend --no-post-rewrite ${gpg_sign_opt:+$gpg_sign_opt} || { + git commit --allow-empty --amend --no-post-rewrite ${gpg_sign_opt:+$gpg_sign_opt} || { warn Could not amend commit after successfully picking $sha1... $rest warn This is most likely due to an empty commit message, or the pre-commit hook warn failed. If the pre-commit hook failed, you may need to resolve the issue before diff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh index a95cb2a..f4e886f 100755 --- a/t/t3404-rebase-interactive.sh +++ b/t/t3404-rebase-interactive.sh @@ -75,6 +75,39 @@ test_expect_success 'rebase --keep-empty' ' test_line_count = 6 actual ' +test_expect_success 'rebase --keep-empty (reword)' ' + git checkout -b reword-emptybranch emptybranch + set_fake_editor + FAKE_LINES=1 reword 2 git rebase --keep-empty -i HEAD~2 + git log --oneline actual + test_line_count = 6 actual +' + +test_expect_success 'rebase --keep-empty (edit)' ' + git checkout -b edit-emptybranch emptybranch + set_fake_editor + FAKE_LINES=1 edit 2 git rebase --keep-empty -i HEAD~2 + git rebase --continue + git log --oneline actual + test_line_count = 6 actual +' + +test_expect_success 'rebase --keep-empty (fixup)' ' + git checkout -b fixup-emptybranch emptybranch + set_fake_editor + FAKE_LINES=1 fixup 2 git rebase --keep-empty -i HEAD~2 + git log --oneline actual + test_line_count = 5 actual +' + +test_expect_success 'rebase --keep-empty (squash)' ' + git checkout -b squash-emptybranch emptybranch + set_fake_editor + FAKE_LINES=1 squash 2 git rebase --keep-empty -i HEAD~2 + git log --oneline actual + test_line_count = 5 actual +' + test_expect_success 'rebase -i with the exec command' ' git checkout master ( -- 2.0.1 -- To unsubscribe from this list: send the line unsubscribe git in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 04/27] fake_editor: leave standard output unchanged
The helper function `set_fake_editor` installs a script as `GIT_EDITOR` that applies pre-defined editing rules to the files it is called with, which is a quite powerful tool when writing test cases for git-rebase--interactive. To aid in debugging the changes it makes, the installed script dumps the file contents to stdout before and after editing. That interferes with the output from git-rebase--interactive, however, and the debug information has to be removed from stdout in a error-prone way. Print the editor contents on stderr instead. When a test case wants to analyse stderr, we need to come up with a different solution. The less convenient possibility that always remains is to store the debug output in a file in the trash directory or even keeping copies of the edited files before and after editing. Signed-off-by: Fabian Ruch baf...@gmail.com --- t/lib-rebase.sh | 8 t/t3404-rebase-interactive.sh | 18 ++ 2 files changed, 10 insertions(+), 16 deletions(-) diff --git a/t/lib-rebase.sh b/t/lib-rebase.sh index 6bd2522..0cd1193 100644 --- a/t/lib-rebase.sh +++ b/t/lib-rebase.sh @@ -41,8 +41,8 @@ set_fake_editor () { test -z $FAKE_LINES exit grep -v '^#' $1 $1.tmp rm -f $1 - echo 'rebase -i script before editing:' - cat $1.tmp + echo 'rebase -i script before editing:' 2 + cat $1.tmp 2 action=pick for line in $FAKE_LINES; do case $line in @@ -59,8 +59,8 @@ set_fake_editor () { action=pick;; esac done - echo 'rebase -i script after editing:' - cat $1 + echo 'rebase -i script after editing:' 2 + cat $1 2 EOF test_set_editor $(pwd)/fake-editor.sh diff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh index f4e886f..7cc6ebf 100755 --- a/t/t3404-rebase-interactive.sh +++ b/t/t3404-rebase-interactive.sh @@ -882,9 +882,8 @@ test_expect_success 'running git rebase -i --exec git show HEAD' ' ( FAKE_LINES=1 exec_git_show_HEAD 2 exec_git_show_HEAD export FAKE_LINES - git rebase -i HEAD~2 expect + git rebase -i HEAD~2 expected ) - sed -e 1,9d expect expected test_cmp expected actual ' @@ -896,9 +895,8 @@ test_expect_success 'running git rebase --exec git show HEAD -i' ' ( FAKE_LINES=1 exec_git_show_HEAD 2 exec_git_show_HEAD export FAKE_LINES - git rebase -i HEAD~2 expect + git rebase -i HEAD~2 expected ) - sed -e 1,9d expect expected test_cmp expected actual ' @@ -910,9 +908,8 @@ test_expect_success 'running git rebase -ix git show HEAD' ' ( FAKE_LINES=1 exec_git_show_HEAD 2 exec_git_show_HEAD export FAKE_LINES - git rebase -i HEAD~2 expect + git rebase -i HEAD~2 expected ) - sed -e 1,9d expect expected test_cmp expected actual ' @@ -924,9 +921,8 @@ test_expect_success 'rebase -ix with several CMD' ' ( FAKE_LINES=1 exec_git_show_HEAD;_pwd 2 exec_git_show_HEAD;_pwd export FAKE_LINES - git rebase -i HEAD~2 expect + git rebase -i HEAD~2 expected ) - sed -e 1,9d expect expected test_cmp expected actual ' @@ -939,9 +935,8 @@ test_expect_success 'rebase -ix with several instances of --exec' ' FAKE_LINES=1 exec_git_show_HEAD exec_pwd 2 exec_git_show_HEAD exec_pwd export FAKE_LINES - git rebase -i HEAD~2 expect + git rebase -i HEAD~2 expected ) - sed -e 1,11d expect expected test_cmp expected actual ' @@ -965,9 +960,8 @@ test_expect_success 'rebase -ix with --autosquash' ' git checkout -b autosquash_expected FAKE_LINES=1 fixup 3 fixup 4 exec_git_show_HEAD 2 exec_git_show_HEAD export FAKE_LINES - git rebase -i HEAD~4 expect + git rebase -i HEAD~4 expected ) - sed -e 1,13d expect expected test_cmp expected actual ' -- 2.0.1 -- To unsubscribe from this list: send the line unsubscribe git in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 01/27] rebase -i: allow replaying commits with empty log messages
git-rebase--interactive handles empty log messages inconsistently between enabled and disabled fast-forwards. By default, commits with empty log messages are rebased successfully like in non-interactive mode. In contrast, the `--no-ff` option aborts the replay of such commits. In line with not verifying rebased commits and behaving like git-rebase for `pick` lines, use the `--allow-empty-message` option to replay commits. Root commits are replayed by recreating them in `do_pick` using git-commit and all other commits are replayed using git-cherry-pick in `pick_one`. Apply the option, understood by both git-commit and git-cherry-pick, at the respective sites. In case of `reword` and `squash`, continue to abort the rebase if the _resulting_ commit would have no commit message. The rationale behind this default is that patches and their log messages should be verified at least once. For unchanged commits this is assumed to have happened according to the author's standards when she created the commits for the first time. While the empty log message can always be kept in place by editing and resuming the aborted rebase, a debatable alternative could be to teach git-rebase--interactive the option `--allow-empty-message` for disabling complaints about empty log messages even in changed commits. The `fixup` case is different again because it throws away the second commit's log message and uses the first log message for the changed commit. Do not abort the rebase if that message is empty either since it is assumed to have been verified already. The remaining to-do list command `edit` is handled just like `pick` for this matter, because git-rebase--interactive replays the named commit without changes before the rebase is interrupted and the user can make her changes to the replayed commit. Add tests. In particular, design the `squash`-specific test case such that it involves interim commits and `fixup` steps. Interim commits should not trigger failures themselves and `fixup` steps should not let git-rebase--interactive forget that it is still dealing with a `squash` result. Signed-off-by: Fabian Ruch baf...@gmail.com --- git-rebase--interactive.sh| 10 ++ t/t3404-rebase-interactive.sh | 38 ++ t/t3412-rebase-root.sh| 16 3 files changed, 60 insertions(+), 4 deletions(-) diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh index b64dd28..3222bf6 100644 --- a/git-rebase--interactive.sh +++ b/git-rebase--interactive.sh @@ -249,7 +249,7 @@ pick_one () { test -d $rewritten pick_one_preserving_merges $@ return - output eval git cherry-pick \ + output eval git cherry-pick --allow-empty-message \ ${gpg_sign_opt:+$(git rev-parse --sq-quote $gpg_sign_opt)} \ $strategy_args $empty_args $ff $@ } @@ -363,7 +363,7 @@ pick_one_preserving_merges () { echo $sha1 $(git rev-parse HEAD^0) $rewritten_list ;; *) - output eval git cherry-pick \ + output eval git cherry-pick --allow-empty-message \ ${gpg_sign_opt:+$(git rev-parse --sq-quote $gpg_sign_opt)} \ $strategy_args $@ || die_with_patch $sha1 Could not pick $sha1 @@ -549,7 +549,8 @@ do_next () { squash|s|fixup|f) # This is an intermediate commit; its message will only be # used in case of trouble. So use the long version: - do_with_author output git commit --amend --no-verify -F $squash_msg \ + do_with_author output git commit --allow-empty-message \ + --amend --no-verify -F $squash_msg \ ${gpg_sign_opt:+$gpg_sign_opt} || die_failed_squash $sha1 $rest ;; @@ -557,7 +558,8 @@ do_next () { # This is the final command of this squash/fixup group if test -f $fixup_msg then - do_with_author git commit --amend --no-verify -F $fixup_msg \ + do_with_author git commit --allow-empty-message \ + --amend --no-verify -F $fixup_msg \ ${gpg_sign_opt:+$gpg_sign_opt} || die_failed_squash $sha1 $rest else diff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh index 8197ed2..9c71835 100755 --- a/t/t3404-rebase-interactive.sh +++ b/t/t3404-rebase-interactive.sh @@ -1039,4 +1039,42 @@ test_expect_success 'short SHA-1 collide' ' ) ' +test_expect_success 'setup commits with empty commit log
[PATCH v3 08/27] rebase -i: verify squash messages using commit-msg
Using the to-do list command `squash` the user can specify two or more commits and git-rebase creates one commit that introduces all their changes combined. The authorship for the created commit is taken from the first commit specified and the user can edit the log message. There is a variant of `squash` available named `fixup` which also takes the first log message without asking for user input. While it is reasonable to not verify replayed changes twice or rejecting some other author's changes in her name, it is insufficient to not verify the user input used as log message in the case of `squash`. Specify the git-commit option `--no-pre-commit` instead of `--no-verify` when committing the squash result, but not before, to let the commit-msg hook verify the final squash message. For the same reasons the pre-commit hook is disabled in all replay modes, the commit-msg hook is disabled in `fixup` mode. Add tests. In addition to the existing test checking that the pre-commit hook is disabled when simply picking a commit, provide a test checking that the commit-msg hook is disabled as well. Signed-off-by: Fabian Ruch baf...@gmail.com --- git-rebase--interactive.sh| 2 +- t/t3404-rebase-interactive.sh | 80 +++ 2 files changed, 81 insertions(+), 1 deletion(-) diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh index cf62daa..54c4614 100644 --- a/git-rebase--interactive.sh +++ b/git-rebase--interactive.sh @@ -562,7 +562,7 @@ do_next () { else cp $squash_msg $GIT_DIR/SQUASH_MSG || exit rm -f $GIT_DIR/MERGE_MSG - do_with_author output git commit --allow-empty --amend --no-verify -F $GIT_DIR/SQUASH_MSG -e \ + do_with_author output git commit --allow-empty --amend --no-pre-commit -F $GIT_DIR/SQUASH_MSG -e \ ${gpg_sign_opt:+$gpg_sign_opt} || die_failed_squash $sha1 $rest fi diff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh index 7cc6ebf..abb829e 100755 --- a/t/t3404-rebase-interactive.sh +++ b/t/t3404-rebase-interactive.sh @@ -664,6 +664,86 @@ test_expect_success 'rebase a commit violating pre-commit' ' ' +test_expect_success 'setup failing pre-commit' ' + HOOKDIR=$(git rev-parse --git-dir)/hooks + mkdir -p $HOOKDIR + PRE_COMMIT=$HOOKDIR/pre-commit + cat $PRE_COMMIT -EOF + #!/bin/sh + echo running failing pre-commit... + exit 1 + EOF + chmod +x $PRE_COMMIT + git checkout -b violating-pre-commit master + test_must_fail test_commit pre-commit-violated-1 + test_commit --no-verify pre-commit-violated-1 + test_must_fail test_commit pre-commit-violated-2 + test_commit --no-verify pre-commit-violated-2 + test_must_fail test_commit pre-commit-violated-3 + test_commit --no-verify pre-commit-violated-3 +' + +test_expect_success 'squash commits violating pre-commit' ' + git checkout -b squash-violating-pre-commit violating-pre-commit + test_when_finished reset_rebase + set_fake_editor + env FAKE_LINES=1 squash 2 squash 3 git rebase -i master +' + +test_expect_success 'fixup commits violating pre-commit' ' + git checkout -b fixup-violating-pre-commit violating-pre-commit + test_when_finished reset_rebase + set_fake_editor + env FAKE_LINES=1 fixup 2 fixup 3 git rebase -i master +' + +test_expect_success 'clean up failing pre-commit' ' + rm $PRE_COMMIT +' + +test_expect_success 'setup failing commit-msg' ' + HOOKDIR=$(git rev-parse --git-dir)/hooks + mkdir -p $HOOKDIR + COMMIT_MSG=$HOOKDIR/commit-msg + cat $COMMIT_MSG -EOF + #!/bin/sh + echo running failing commit-msg... + exit 1 + EOF + chmod +x $COMMIT_MSG + git checkout -b violating-commit-msg master + test_must_fail test_commit commit-msg-violated-1 + test_commit --no-verify commit-msg-violated-1 + test_must_fail test_commit commit-msg-violated-2 + test_commit --no-verify commit-msg-violated-2 + test_must_fail test_commit commit-msg-violated-3 + test_commit --no-verify commit-msg-violated-3 +' + +test_expect_success 'rebase a commit violating commit-msg' ' + git checkout -b rebase-violating-commit-msg violating-commit-msg + set_fake_editor + FAKE_LINES=1 git rebase -i master +' + +test_expect_success 'squash commits violating commit-msg' ' + git checkout -b squash-violating-commit-msg violating-commit-msg + set_fake_editor + test_must_fail env FAKE_LINES=1 squash 2 squash 3 git rebase -i master + git commit --no-verify --amend + git rebase --continue +' + +test_expect_success 'fixup commits violating
[PATCH v3 02/27] rebase -i: allow squashing empty commits without complaints
The to-do list commands `squash` and `fixup` apply the changes introduced by the named commit to the tree but instead of creating a new commit on top of the current head it replaces the previous commit with a new commit that records the updated tree. If the result is an empty commit git-rebase stops with the error message You asked to amend the most recent commit, but doing so would make it empty. You can repeat your command with --allow-empty, or you can remove the commit entirely with git reset HEAD^. This message is not very helpful because neither does git-rebase support an option `--allow-empty` nor does the messages say how to resume the rebase. Firstly, change the error message to The squash result is empty and --keep-empty was not specified. You can remove the squash commit now with git reset HEAD^ Once you are done, run git rebase --continue If the user wishes to squash a sequence of commits into one commit, f. i. pick A squash Revert A squash A' , it does not matter for the end result that the first squash result, or any sub-sequence in general, is going to be empty. The squash message is not affected at all by which commits are created and only the commit created by the last line in the sequence will end up in the final history. Secondly, print the error message only if the whole squash sequence produced an empty commit. Lastly, since an empty squash commit is not a failure to rewrite the history as planned, issue the message above as a mere warning and interrupt the rebase with the return value zero. The interruption should be considered as a notification with the chance to undo it on the spot. Specifying the `--keep-empty` option tells git-rebase to keep empty squash commits in the rebased history without notification. Add tests. Reported-by: Peter Krefting pe...@softwolves.pp.se Signed-off-by: Fabian Ruch baf...@gmail.com --- git-rebase--interactive.sh| 20 +++--- t/t3404-rebase-interactive.sh | 62 +++ 2 files changed, 79 insertions(+), 3 deletions(-) diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh index 3222bf6..ada340c 100644 --- a/git-rebase--interactive.sh +++ b/git-rebase--interactive.sh @@ -549,7 +549,7 @@ do_next () { squash|s|fixup|f) # This is an intermediate commit; its message will only be # used in case of trouble. So use the long version: - do_with_author output git commit --allow-empty-message \ + do_with_author output git commit --allow-empty-message --allow-empty \ --amend --no-verify -F $squash_msg \ ${gpg_sign_opt:+$gpg_sign_opt} || die_failed_squash $sha1 $rest @@ -558,18 +558,32 @@ do_next () { # This is the final command of this squash/fixup group if test -f $fixup_msg then - do_with_author git commit --allow-empty-message \ + do_with_author git commit --allow-empty-message --allow-empty \ --amend --no-verify -F $fixup_msg \ ${gpg_sign_opt:+$gpg_sign_opt} || die_failed_squash $sha1 $rest else cp $squash_msg $GIT_DIR/SQUASH_MSG || exit rm -f $GIT_DIR/MERGE_MSG - do_with_author git commit --amend --no-verify -F $GIT_DIR/SQUASH_MSG -e \ + do_with_author git commit --allow-empty --amend --no-verify -F $GIT_DIR/SQUASH_MSG -e \ ${gpg_sign_opt:+$gpg_sign_opt} || die_failed_squash $sha1 $rest fi rm -f $squash_msg $fixup_msg + if test -z $keep_empty is_empty_commit HEAD + then + echo $sha1 $state_dir/stopped-sha + warn The squash result is empty and --keep-empty was not specified. + warn + warn You can remove the squash commit now with + warn + warn git reset HEAD^ + warn + warn Once you are done, run + warn + warn git rebase --continue + exit 0 + fi ;; esac record_in_rewritten $sha1 diff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh index 9c71835..a95cb2a
[PATCH v3 05/27] rebase -i: hide interactive command messages in verbose mode
git-rebase--interactive prints summary messages of the commits it creates in the final history only if the `--verbose` option is specified by the user and suppresses them otherwise. This behaviour is implemented by wrapping git-commit calls in a shell function named `output` which redirects stderr to stdout, captures stdout in a shell variable and ignores its contents unless the command exits with an error status. The command lines used to implement the to-do list commands `reword` and `squash` print diagnostic messages even in non-verbose mode. The reason for this inconsistency is that both commands launch the log message editor `GIT_EDITOR` which usually requires a working terminal attached to stdin. Wrapping the `reword` and `squash` command lines in `output` would seemingly freeze the terminal (see commit 7725cb5, rebase -i: fix reword when using a terminal editor). Temporarily redirect the `GIT_EDITOR` output to a third file descriptor in order to ship it around the capture stream. Wrap the remaining git-commit command lines in the new `output`. At the moment, it is still no alternative to pass the `--quiet` option in non-verbose mode because git-merge-recursive for instance prints some messages regardless of the verbosity level. In order to temporarily redirect the editor output, the new definition of `output` creates a wrapper script in the state directory to be used as `GIT_EDITOR`. Make sure the state directory exists before `output` is called for the first time. Signed-off-by: Fabian Ruch baf...@gmail.com --- git-rebase--interactive.sh | 9 + git-rebase.sh | 13 +++-- t/t3406-rebase-message.sh | 18 ++ 3 files changed, 34 insertions(+), 6 deletions(-) diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh index eb1dcda..cebe742 100644 --- a/git-rebase--interactive.sh +++ b/git-rebase--interactive.sh @@ -504,7 +504,7 @@ do_next () { mark_action_done do_pick $sha1 $rest - git commit --allow-empty --amend --no-post-rewrite ${gpg_sign_opt:+$gpg_sign_opt} || { + output git commit --allow-empty --amend --no-post-rewrite ${gpg_sign_opt:+$gpg_sign_opt} || { warn Could not amend commit after successfully picking $sha1... $rest warn This is most likely due to an empty commit message, or the pre-commit hook warn failed. If the pre-commit hook failed, you may need to resolve the issue before @@ -558,14 +558,14 @@ do_next () { # This is the final command of this squash/fixup group if test -f $fixup_msg then - do_with_author git commit --allow-empty-message --allow-empty \ + do_with_author output git commit --allow-empty-message --allow-empty \ --amend --no-verify -F $fixup_msg \ ${gpg_sign_opt:+$gpg_sign_opt} || die_failed_squash $sha1 $rest else cp $squash_msg $GIT_DIR/SQUASH_MSG || exit rm -f $GIT_DIR/MERGE_MSG - do_with_author git commit --allow-empty --amend --no-verify -F $GIT_DIR/SQUASH_MSG -e \ + do_with_author output git commit --allow-empty --amend --no-verify -F $GIT_DIR/SQUASH_MSG -e \ ${gpg_sign_opt:+$gpg_sign_opt} || die_failed_squash $sha1 $rest fi @@ -923,6 +923,8 @@ EOF ;; esac +mkdir -p $state_dir || die Could not create temporary $state_dir + git var GIT_COMMITTER_IDENT /dev/null || die You need to set your committer info first @@ -938,7 +940,6 @@ then fi orig_head=$(git rev-parse --verify HEAD) || die No HEAD? -mkdir -p $state_dir || die Could not create temporary $state_dir : $state_dir/interactive || die Could not mark as interactive write_basic_state diff --git a/git-rebase.sh b/git-rebase.sh index 55da9db..46141b8 100755 --- a/git-rebase.sh +++ b/git-rebase.sh @@ -131,9 +131,18 @@ write_basic_state () { output () { case $verbose in '') - output=$($@ 21 ) + cat $state_dir/editor.sh -EOF + #!/bin/sh + $(git var GIT_EDITOR) \$@ 3 + EOF + chmod +x $state_dir/editor.sh + ( + GIT_EDITOR=$(git rev-parse --sq-quote $state_dir/editor.sh) + export GIT_EDITOR + $@ 31 1$state_dir/output 21 + ) status=$? - test $status != 0 printf %s\n $output + test $status != 0 cat $state_dir/output return $status
[PATCH v3 06/27] rebase -i: discard redundant message when rewording fails
The to-do list command `reword` replays a commit like `pick` but lets the user also edit the commit's log message. If the edited log message is empty or is found ill-formatted by one of the commit hooks, git-rebase--interactive prints three error messages to the console. 1. The git-commit output, which contains all the output from hook scripts. 2. A rebase diagnosis saying at which task on the to-do list it got stuck. 3. Generic presumptions about what could have triggered the error. The third message contains redundant information and does not add any enlightenment either, which makes the output unnecessarily longish and different from the other commands' output. For instance, this is what the output looks like if the log message is empty (contains duplicate Signed-off-by lines). (1.) Aborting commit due to empty commit message. (Duplicate Signed-off-by lines.) (2.) Could not amend commit after successfully picking fa1afe1... Some change (3.) This is most likely due to an empty commit message, or the pre-commit hook failed. If the pre-commit hook failed, you may need to resolve the issue before you are able to reword the commit. Discard the third message. It is true that a failed hook script might not output any diagnosis but then the generic message is not of much help either. Since this lack of information affects the built-in git commands for commit, merge and cherry-pick first, the solution would be to keep track of the failed hooks in their output so that the user knows which of her hooks require improvement. Signed-off-by: Fabian Ruch baf...@gmail.com --- git-rebase--interactive.sh | 3 --- 1 file changed, 3 deletions(-) diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh index cebe742..cf62daa 100644 --- a/git-rebase--interactive.sh +++ b/git-rebase--interactive.sh @@ -506,9 +506,6 @@ do_next () { do_pick $sha1 $rest output git commit --allow-empty --amend --no-post-rewrite ${gpg_sign_opt:+$gpg_sign_opt} || { warn Could not amend commit after successfully picking $sha1... $rest - warn This is most likely due to an empty commit message, or the pre-commit hook - warn failed. If the pre-commit hook failed, you may need to resolve the issue before - warn you are able to reword the commit. exit_with_patch $sha1 1 } record_in_rewritten $sha1 -- 2.0.1 -- To unsubscribe from this list: send the line unsubscribe git in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 25/27] rebase -i: do not overwrite user author information
The shell function `get_author_ident_from_commit` defined by git-sh-setup retrieves the author information from the named commit and returns assignments of the environment variables GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL GIT_AUTHOR_DATE ready for evaluation by the shell. This interface is used in conjunction with the so-called author script which is a git-rebase--interactive state file that contains the `get_author_ident_from_commit` output. It is sourced when `git rebase --continue` is executed after conflict resolution to retain the original commit authorship. The variable assignments are only exported by the subshell that executes the git-commit command line that commits the resolved conflicts. That is taken care of by wrapping the git-commit call in `do_with_author`. However, this is not enough protection from modifying the git environment variables unintentionally because the user running git-rebase could have already exported those herself. And therefore, a bare git-commit could result in an authorship that is neither intended by the user nor by git-rebase--interactive. While it is not an issue now (either `do_with_author`, git-cherry-pick or `--amend` are used to create commits), the unnecessary loss of the author name and e-mail copied from the user environment, and the unneeded fixing of the author date might become a problem when we decide to support something similar to `--reset-author` or `--ignore-date in interactive git-rebase. Do not assign the git environment variables until in the `do_with_author` subshell. Signed-off-by: Fabian Ruch baf...@gmail.com --- git-rebase--interactive.sh | 19 ++- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh index 73c97a1..8fbfe6d 100644 --- a/git-rebase--interactive.sh +++ b/git-rebase--interactive.sh @@ -166,7 +166,7 @@ make_patch () { test -f $msg || commit_message $1 $msg test -f $author_script || - get_author_ident_from_commit $1 $author_script + echo $1 $author_script } die_with_patch () { @@ -215,9 +215,13 @@ is_merge_commit() } # Run command with GIT_AUTHOR_NAME, GIT_AUTHOR_EMAIL, and -# GIT_AUTHOR_DATE exported from the current environment. +# GIT_AUTHOR_DATE assigned the author information extracted from the +# named commit and exported. do_with_author () { ( + sha1=$1 + shift + eval $(get_author_ident_from_commit $sha1) export GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL GIT_AUTHOR_DATE $@ ) @@ -348,13 +352,11 @@ pick_one_preserving_merges () { test a$1 = a-n die Refusing to squash a merge: $sha1 # redo merge - author_script_content=$(get_author_ident_from_commit $sha1) - eval $author_script_content msg_content=$(commit_message $sha1) # No point in merging the first parent, that's HEAD new_parents=${new_parents# $first_parent} merge_args=--no-log --no-ff - if ! do_with_author output eval \ + if ! do_with_author $sha1 output eval \ 'git merge ${gpg_sign_opt:+$gpg_sign_opt} \ $merge_args $strategy_args -m $msg_content $new_parents' then @@ -592,8 +594,7 @@ do_pick () { do_with_author= if test -z $rewrite_reset_author test -z $rewrite_amend then - eval $(get_author_ident_from_commit $1) - do_with_author=do_with_author + do_with_author=do_with_author $1 fi $do_with_author output git commit \ --allow-empty --no-post-rewrite -n --no-edit \ @@ -1041,9 +1042,9 @@ first and then run 'git rebase --continue' again. ${gpg_sign_opt:+$gpg_sign_opt} || die Could not commit staged changes. else - . $author_script || + test -r $author_script || die Error trying to find the author identity to amend commit - do_with_author git commit --no-verify -F $msg -e \ + do_with_author $(cat $author_script) git commit --no-verify -F $msg -e \ ${gpg_sign_opt:+$gpg_sign_opt} || die Could not commit staged changes. fi -- 2.0.1 -- To unsubscribe from this list: send the line unsubscribe git in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 24/27] rebase -i: teach do_pick the option --signoff
`do_pick` is the git-cherry-pick wrapper in git-rebase--interactive that is currently used to implement most of the to-do list commands and offers additional options that will eventually find their way onto to-do lists. To extend the repertoire of available options, add the git-commit and git-cherry-pick option `--signoff` to the `do_pick` interface. It appends a Signed-off-by: line using the committer identity to the log message of the picked commit. Signed-off-by: Fabian Ruch baf...@gmail.com --- git-rebase--interactive.sh | 13 - 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh index 6c75bc5..73c97a1 100644 --- a/git-rebase--interactive.sh +++ b/git-rebase--interactive.sh @@ -464,10 +464,15 @@ record_in_rewritten() { # Apply the changes introduced by the given commit to the current head. # -# do_pick [--reset-author] [--amend] [--file file] [--edit] commit +# do_pick [--signoff] [--reset-author] [--amend] [--file file] +# [--edit] commit # # Wrapper around git-cherry-pick. # +# -s, --signoff +# Insert a Signed-off-by: line using the committer identity at the +# end of the commit log message. This creates a fresh commit. +# # --reset-author # Pretend the changes were made for the first time. Declare that the # authorship of the resulting commit now belongs to the committer. @@ -504,6 +509,7 @@ record_in_rewritten() { do_pick () { allow_empty_message=y rewrite= + rewrite_signoff= rewrite_reset_author= rewrite_amend= rewrite_edit= @@ -511,6 +517,10 @@ do_pick () { while test $# -gt 0 do case $1 in + -s|--signoff) + rewrite=y + rewrite_signoff=y + ;; --reset-author) rewrite=y rewrite_reset_author=y @@ -588,6 +598,7 @@ do_pick () { $do_with_author output git commit \ --allow-empty --no-post-rewrite -n --no-edit \ ${allow_empty_message:+--allow-empty-message} \ + ${rewrite_signoff:+--signoff} \ ${rewrite_amend:+--amend ${rewrite_reset_author:+--reset-author}} \ ${rewrite_edit:+--edit --commit-msg} \ ${rewrite_message:+--file $rewrite_message} \ -- 2.0.1 -- To unsubscribe from this list: send the line unsubscribe git in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 23/27] rebase -i: teach do_pick the option --reset-author
`do_pick` is the git-cherry-pick wrapper in git-rebase--interactive that is used to implement many of the to-do list commands. Eventually, the complete `do_pick` interface will be exposed to the user in some form or another and those commands will become simple aliases for the `do_pick` options now used to implement them. Add the git-commit option `--reset-author` to the options pool of `do_pick`. It rewrites the author date and name of the picked commit to match the committer date and name. If `--reset-author` is passed to `do_pick`, set the `rewrite` flag and relay the option to the git-commit command line which creates the final commit. If `--amend` is not passed as well, the fresh authorship effect is achieved by the mere fact that we are creating a new commit. Do not even source the ident information in that case because the user shell might have already exported the respective environment variables. Signed-off-by: Fabian Ruch baf...@gmail.com --- git-rebase--interactive.sh | 26 ++ 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh index 8b39f2d..6c75bc5 100644 --- a/git-rebase--interactive.sh +++ b/git-rebase--interactive.sh @@ -464,10 +464,18 @@ record_in_rewritten() { # Apply the changes introduced by the given commit to the current head. # -# do_pick [--amend] [--file file] [--edit] commit +# do_pick [--reset-author] [--amend] [--file file] [--edit] commit # # Wrapper around git-cherry-pick. # +# --reset-author +# Pretend the changes were made for the first time. Declare that the +# authorship of the resulting commit now belongs to the committer. +# This also renews the author timestamp. This creates a fresh +# commit. +# +# _This is not a git-cherry-pick option._ +# # --amend # After picking commit, replace the current head commit with a new # commit that also introduces the changes of commit. @@ -496,12 +504,17 @@ record_in_rewritten() { do_pick () { allow_empty_message=y rewrite= + rewrite_reset_author= rewrite_amend= rewrite_edit= rewrite_message= while test $# -gt 0 do case $1 in + --reset-author) + rewrite=y + rewrite_reset_author=y + ;; --amend) if test $(git rev-parse HEAD) = $squash_onto || ! git rev-parse -q --verify HEAD /dev/null then @@ -566,11 +579,16 @@ do_pick () { if test -n $rewrite then - eval $(get_author_ident_from_commit $1) - do_with_author output git commit \ + do_with_author= + if test -z $rewrite_reset_author test -z $rewrite_amend + then + eval $(get_author_ident_from_commit $1) + do_with_author=do_with_author + fi + $do_with_author output git commit \ --allow-empty --no-post-rewrite -n --no-edit \ ${allow_empty_message:+--allow-empty-message} \ - ${rewrite_amend:+--amend} \ + ${rewrite_amend:+--amend ${rewrite_reset_author:+--reset-author}} \ ${rewrite_edit:+--edit --commit-msg} \ ${rewrite_message:+--file $rewrite_message} \ ${gpg_sign_opt:+$gpg_sign_opt} || return 3 -- 2.0.1 -- To unsubscribe from this list: send the line unsubscribe git in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 27/27] rebase -i: enable --signoff, --reset-author for pick, reword, edit
Lift the general unknown option blockade for the `pick`, `reword` and `edit` commands. If `do_cmd` comes across one of the options `--signoff` and `--reset-author` while parsing a to-do entry and the scheduled command is either `pick` or `reword`, relay the option to `do_pick`. Remember to add Signed-off-by: and to reset the authorship even when the rebase is interrupted for conflict resolution and `git rebase --continue` creates the commit. Employ the same mechanism that is used to remember amending an interim squash commit after conflict resolution or a commit after editing. If a line option was specified, create the files `signoff` and `resetauthor` respectively in the state directory. While `signoff` is handled by simply specifying the `--signoff` option when creating the commit, the `resetauthor` case is somewhat more involved. The author script contains the author information of the replayed commit. Renewing the authorship means using the user environment for the authorship so that we need to skip the author script if `resetauthor` exists and we are not amending. If we are amending, `--reset-author` must be passed to git-commit because otherwise the authorship of HEAD would be used. `do_pick` options like `--gpg-sign` and `--file` are not yet supported because `do_cmd` cannot handle option arguments and options with spaces at the moment. `squash` and `fixup` still do not accept user options as the interplay of `--reset-author` and the author script is yet to be determined. Document the new options by listing them in the to-do help and giving a usage example in the INTERACTIVE MODE section of the git-rebase man page. Add tests. Signed-off-by: Fabian Ruch baf...@gmail.com --- Documentation/git-rebase.txt | 13 +++ git-rebase--interactive.sh | 38 +++- t/t3427-rebase-line-options.sh | 192 - 3 files changed, 240 insertions(+), 3 deletions(-) diff --git a/Documentation/git-rebase.txt b/Documentation/git-rebase.txt index 2a93c64..10c0fd2 100644 --- a/Documentation/git-rebase.txt +++ b/Documentation/git-rebase.txt @@ -508,6 +508,19 @@ rebasing. If you just want to edit the commit message for a commit, replace the command pick with the command reword. +The commands pick, reword and edit understand some well-known +options. To add a Signed-off-by line at the end of the commit +message, pass the `--signoff` option. The authorship can be renewed +by specifying the `--reset-author` option. For instance, before you +decide to publish a heavily edited commit you might want to reset the +authorship and add your signature. You can do so on a per line basis: + +--- +pick deadbee The oneline of this commit +pick --reset-author --signoff fa1afe1 The oneline of the next commit +... +--- + If you want to fold two or more commits into one, replace the command pick for the second and subsequent commits with squash or fixup. If the commits had different authors, the folded commit will be diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh index 51ee80c..0db5001 100644 --- a/git-rebase--interactive.sh +++ b/git-rebase--interactive.sh @@ -72,9 +72,15 @@ last_head=$state_dir/last_head # file 'amend' is created. When git rebase --continue is executed, # if there are any staged changes then they will be amended to the # HEAD commit, but only provided the HEAD commit is still the commit -# to be edited or the squash commit. When any other rebase command is +# to be edited or the squash commit. Similarly, when a Signed-off-by: +# should be added to a log message or the authorship should be +# renewed, the files 'signoff' and 'resetauthor' are created +# respectively, and git rebase --continue carries out the changes +# after conflict resolution. When any other rebase command is # processed, these files are deleted. amend=$state_dir/amend +signoff=$state_dir/signoff +resetauthor=$state_dir/resetauthor # For the post-rewrite hook, we make a list of rewritten commits and # their new sha1s. The rewritten-pending list keeps the sha1s of @@ -149,6 +155,10 @@ Commands: f, fixup = like squash, but discard this commit's log message x, exec = run command (the rest of the line) using shell +Options: + [pick | reword | edit] --signoff = add a Signed-off-by line + [pick | reword | edit] --reset-author = renew authorship + These lines can be re-ordered; they are executed from top to bottom. If you remove a line here THAT COMMIT WILL BE LOST. @@ -528,10 +538,12 @@ do_pick () { -s|--signoff) rewrite=y rewrite_signoff=y + $signoff ;; --reset-author) rewrite=y rewrite_reset_author=y + $resetauthor ;; --amend) if
[PATCH v3 07/27] commit: allow disabling pre-commit and commit-msg separately
Introduce the git-commit command line options `--no-pre-commit` and `--no-commit-msg` to disable the pre-commit and commit-msg hooks, respectively. Make `--no-verify` a synonym for specifying both at the same time. This change is motivated by an internal usage of git-commit in git-rebase--interactive to disable pre-commit while keeping commit-msg enabled when rewording a commit. Make `test_commit` forward unknown options to git-commit instead of teaching it all possible options. In order to support leading double dashes in `message`, stop interpreting `test_commit` arguments following a `--` argument as options. This wasn't a problem before because the first unknown option would be used as `message`. Allow disabling tag creation to avoid name clashes when using `test_commit` with the same arguments several times from the same test suite. By default, `test_commit` tags successful commits using git-tag for easy reference. The `--notag` option skips this step. Add tests. Signed-off-by: Fabian Ruch baf...@gmail.com --- Documentation/git-commit.txt | 8 - builtin/commit.c | 32 ++--- t/t7503-pre-commit-hook.sh | 65 - t/t7504-commit-msg-hook.sh | 85 ++-- t/test-lib-functions.sh | 23 5 files changed, 176 insertions(+), 37 deletions(-) diff --git a/Documentation/git-commit.txt b/Documentation/git-commit.txt index 0bbc8f5..28a2c5c 100644 --- a/Documentation/git-commit.txt +++ b/Documentation/git-commit.txt @@ -158,7 +158,7 @@ OPTIONS -n:: --no-verify:: - This option bypasses the pre-commit and commit-msg hooks. + A synonym for `--no-pre-commit --no-commit-msg`. See also linkgit:githooks[5]. --allow-empty:: @@ -238,6 +238,12 @@ You should understand the implications of rewriting history if you amend a commit that has already been published. (See the RECOVERING FROM UPSTREAM REBASE section in linkgit:git-rebase[1].) +--no-pre-commit:: + This option bypasses the pre-commit hook. + +--no-commit-msg:: + This option bypasses the commit-msg hook. + --no-post-rewrite:: Bypass the post-rewrite hook. diff --git a/builtin/commit.c b/builtin/commit.c index 5ed6036..dfd354e 100644 --- a/builtin/commit.c +++ b/builtin/commit.c @@ -98,12 +98,27 @@ static char *edit_message, *use_message; static char *fixup_message, *squash_message; static int all, also, interactive, patch_interactive, only, amend, signoff; static int edit_flag = -1; /* unspecified */ -static int quiet, verbose, no_verify, allow_empty, dry_run, renew_authorship; +static int quiet, verbose, allow_empty, dry_run, renew_authorship; static int no_post_rewrite, allow_empty_message; static char *untracked_files_arg, *force_date, *ignore_submodule_arg; static char *sign_commit; /* + * The verify variable is interpreted as a bitmap of enabled commit + * verification hooks according to the legend below. + * + * By default, the pre-commit and commit-msg hooks are enabled. This + * is represented by both the PRE_COMMIT and COMMIT_MSG bits being + * set. + * + * The bitmap is changed through the command line options + * --no-verify, --no-pre-commit and --no-commit-msg. + */ +#define PRE_COMMIT (10) +#define COMMIT_MSG (11) +static int verify = PRE_COMMIT | COMMIT_MSG; + +/* * The default commit message cleanup mode will remove the lines * beginning with # (shell comments) and leading and trailing * whitespaces (empty lines or containing only whitespaces) @@ -661,7 +676,8 @@ static int prepare_to_commit(const char *index_file, const char *prefix, /* This checks and barfs if author is badly specified */ determine_author_info(author_ident); - if (!no_verify run_commit_hook(use_editor, index_file, pre-commit, NULL)) + if (verify PRE_COMMIT + run_commit_hook(use_editor, index_file, pre-commit, NULL)) return 0; if (squash_message) { @@ -962,7 +978,7 @@ static int prepare_to_commit(const char *index_file, const char *prefix, } } - if (!no_verify + if (verify COMMIT_MSG run_commit_hook(use_editor, index_file, commit-msg, git_path(commit_editmsg), NULL)) { return 0; } @@ -1590,7 +1606,9 @@ int cmd_commit(int argc, const char **argv, const char *prefix) OPT_BOOL(0, interactive, interactive, N_(interactively add files)), OPT_BOOL('p', patch, patch_interactive, N_(interactively add changes)), OPT_BOOL('o', only, only, N_(commit only specified files)), - OPT_BOOL('n', no-verify, no_verify, N_(bypass pre-commit hook)), + OPT_NEGBIT('n', no-verify, verify, + N_(synonym for --no-pre-commit --no-commit-msg), + PRE_COMMIT | COMMIT_MSG), OPT_BOOL(0, dry-run, dry_run, N_(show what would be committed)),
[PATCH v3 16/27] rebase -i: teach do_pick the option --amend
`do_pick` is the git-cherry-pick wrapper in git-rebase--interactive that is used to implement the to-do list commands `pick`, `reword` and `edit`. To cater for the different pick behaviours (like `squash`), `do_pick` accepts several options not only from the git-cherry-pick but also the git-commit interface. Add the option `--amend` from the git-commit interface to the options pool of `do_pick`. It creates a new commit for the changes introduced by the picked commit and the previous one. The previous commit is then replaced with the new commit. If no other options are specified, the log message of the previous commit is used. Be careful when `--amend` is used to pick a root commit because HEAD might point to the sentinel commit but there is still nothing to amend. Be sure to initialize `amend` so that commits are squashed even when git-rebase--interactive is interrupted for resolving conflicts. It is not a mistake to do the initialization regardless of any conflicts because `amend` is always cleared before the next to-do item is processed. Signed-off-by: Fabian Ruch baf...@gmail.com --- git-rebase--interactive.sh | 18 +- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh index a5a8aa3..20a637a 100644 --- a/git-rebase--interactive.sh +++ b/git-rebase--interactive.sh @@ -464,10 +464,16 @@ record_in_rewritten() { # Apply the changes introduced by the given commit to the current head. # -# do_pick [--edit] commit +# do_pick [--amend] [--edit] commit # # Wrapper around git-cherry-pick. # +# --amend +# After picking commit, replace the current head commit with a new +# commit that also introduces the changes of commit. +# +# _This is not a git-cherry-pick option._ +# # -e, --edit # After picking commit, open an editor and let the user edit the # commit message. The editor contents becomes the commit message of @@ -489,6 +495,16 @@ do_pick () { while test $# -gt 0 do case $1 in + --amend) + if test $(git rev-parse HEAD) = $squash_onto || ! git rev-parse -q --verify HEAD /dev/null + then + warn do_pick: nothing to amend + return 2 + fi + rewrite=y + rewrite_amend=y + git rev-parse --verify HEAD $amend + ;; -e|--edit) rewrite=y rewrite_edit=y -- 2.0.1 -- To unsubscribe from this list: send the line unsubscribe git in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 09/27] rebase -i: do not verify reworded patches using pre-commit
The to-do list command `reword` replays a commit like `pick` but lets the user also edit the commit's log message. This happens in two steps. Firstly, the named commit is cherry-picked. Secondly, the commit created in the first step is amended using an unchanged index to edit the log message. The pre-commit hook is meant to verify the changes introduced by a commit (for instance, catching inserted trailing white space). Since the committed tree is not changed between the two steps and we do not verify rebased patches, do not execute the pre-commit hook in the second step. Specify the git-commit option `--no-pre-commit` to disable the pre-commit hook when editing the log message. The commit-msg hook will still be executed to verify the edited commit log message. As before, if the hook finds the new log message ill-formatted, the rebase will be interrupted with the unchanged commit replayed and the new log message in `$GIT_DIR/COMMIT_EDITMSG`. Add tests. Signed-off-by: Fabian Ruch baf...@gmail.com --- git-rebase--interactive.sh| 2 +- t/t3404-rebase-interactive.sh | 14 ++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh index 54c4614..570c4e9 100644 --- a/git-rebase--interactive.sh +++ b/git-rebase--interactive.sh @@ -504,7 +504,7 @@ do_next () { mark_action_done do_pick $sha1 $rest - output git commit --allow-empty --amend --no-post-rewrite ${gpg_sign_opt:+$gpg_sign_opt} || { + output git commit --allow-empty --amend --no-post-rewrite --no-pre-commit ${gpg_sign_opt:+$gpg_sign_opt} || { warn Could not amend commit after successfully picking $sha1... $rest exit_with_patch $sha1 1 } diff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh index abb829e..ecdab11 100755 --- a/t/t3404-rebase-interactive.sh +++ b/t/t3404-rebase-interactive.sh @@ -683,6 +683,13 @@ test_expect_success 'setup failing pre-commit' ' test_commit --no-verify pre-commit-violated-3 ' +test_expect_success 'reword a commit violating pre-commit' ' + git checkout -b reword-violating-pre-commit violating-pre-commit + test_when_finished reset_rebase + set_fake_editor + env FAKE_LINES=reword 1 git rebase -i master +' + test_expect_success 'squash commits violating pre-commit' ' git checkout -b squash-violating-pre-commit violating-pre-commit test_when_finished reset_rebase @@ -726,6 +733,13 @@ test_expect_success 'rebase a commit violating commit-msg' ' FAKE_LINES=1 git rebase -i master ' +test_expect_success 'reword a commit violating commit-msg' ' + git checkout -b reword-violating-commit-msg violating-commit-msg + test_when_finished reset_rebase + set_fake_editor + test_must_fail env FAKE_LINES=reword 1 git rebase -i master +' + test_expect_success 'squash commits violating commit-msg' ' git checkout -b squash-violating-commit-msg violating-commit-msg set_fake_editor -- 2.0.1 -- To unsubscribe from this list: send the line unsubscribe git in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 26/27] rebase -i: refuse to commit when resuming with updated head
If git-rebase--interactive fails to apply the changes introduced by a commit due to conflicts, it interrupts the rebase process and gives the user a shell to resolve the conflicts manually. The process is resumed when the user executes `git rebase --continue`. If the index has changes, the script assumes that those are to be committed under the authorship and with the log message of the commit it tried to replay last. However, that assumption is most likely incorrect if the user has already committed the resolved changes herself. To prevent committing unrelated changes under the wrong authorship and with the wrong log message, at least check that HEAD is still at the same commit by tracking the hash of the last replayed commit. A similar check already happens before `git rebase --continue` amends the previous commit after an `edit` or a conflicted `squash` command. Signed-off-by: Fabian Ruch baf...@gmail.com --- git-rebase--interactive.sh| 35 +-- t/t3404-rebase-interactive.sh | 12 2 files changed, 33 insertions(+), 14 deletions(-) diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh index 8fbfe6d..51ee80c 100644 --- a/git-rebase--interactive.sh +++ b/git-rebase--interactive.sh @@ -62,13 +62,18 @@ msgnum=$state_dir/msgnum # being rebased. author_script=$state_dir/author-script -# When an edit rebase command is being processed, the SHA1 of the -# commit to be edited is recorded in this file. The same happens when -# rewriting a root commit fails, for instance reword. When git -# rebase --continue is executed, if there are any staged changes then -# they will be amended to the HEAD commit, but only provided the HEAD -# commit is still the commit to be edited. When any other rebase -# command is processed, this file is deleted. +# This file keeps track of the SHA1 of the last replayed commit, the +# new parent of the next commit being replayed. It is used to make +# sure that git rebase --continue only commits resolved conflicts +# or edit changes automatically. +last_head=$state_dir/last_head + +# When an edit or a squash rebase command is being processed, the +# file 'amend' is created. When git rebase --continue is executed, +# if there are any staged changes then they will be amended to the +# HEAD commit, but only provided the HEAD commit is still the commit +# to be edited or the squash commit. When any other rebase command is +# processed, these files are deleted. amend=$state_dir/amend # For the post-rewrite hook, we make a list of rewritten commits and @@ -179,7 +184,8 @@ die_with_patch () { exit_with_patch () { echo $1 $state_dir/stopped-sha make_patch $1 - git rev-parse --verify HEAD $amend + $amend + git rev-parse --verify HEAD $last_head gpg_sign_opt_quoted=${gpg_sign_opt:+$(git rev-parse --sq-quote $gpg_sign_opt)} warn You can amend the commit now, with warn @@ -535,7 +541,7 @@ do_pick () { fi rewrite=y rewrite_amend=y - git rev-parse --verify HEAD $amend + $amend ;; -F|--file) if test $# -eq 0 @@ -572,7 +578,7 @@ do_pick () { then rewrite=y rewrite_amend=y - git rev-parse --verify HEAD $amend + $amend # Set the correct commit message and author info on the # sentinel root before cherry-picking the original changes @@ -734,6 +740,7 @@ do_replay () { do_next () { rm -f $msg $author_script $amend || exit + git rev-parse --verify HEAD $last_head || exit read -r command args $todo case $command in @@ -1031,13 +1038,13 @@ In both case, once you're done, continue with: git rebase --continue fi - if test -f $amend - then - current_head=$(git rev-parse --verify HEAD) - test $current_head = $(cat $amend) || + current_head=$(git rev-parse --verify HEAD) + test $current_head = $(cat $last_head) || die \ You have uncommitted changes in your working tree. Please, commit them first and then run 'git rebase --continue' again. + if test -f $amend + then git commit --amend --no-verify -F $msg -e \ ${gpg_sign_opt:+$gpg_sign_opt} || die Could not commit staged changes. diff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh index c037a07..5955bd8 100755 --- a/t/t3404-rebase-interactive.sh +++ b/t/t3404-rebase-interactive.sh @@ -444,6 +444,18 @@ test_expect_success '--continue tries to commit' ' git show HEAD | grep chouette ' +test_expect_success '--continue does not commit
[PATCH v3 18/27] rebase -i: remove no-op do_with_author git commit --amend
The author script is a file in the state directory that contains assignments of the environment variables GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL GIT_AUTHOR_DATE to be evaluated by the shell. It is used to store author information and has two applications in `git-rebase--interactive.sh`. Firstly, the authorship of squash commits is read from it while the squash commit is being amended step by step. Secondly, after conflict resolution `git rebase --continue` restores the author information of the original commit by sourcing the author script. For the assignments of the git environment variables to take effect, git-rebase--interactive executes the respective git-commit commands wrapped in `do_with_author`. That shell function executes the named command in a subshell that exports the git environment variables. Since git commit --amend has been used instead of git reset --soft HEAD^ git commit to amend squash commits, wrapping git-commit in `do_with_author` has become a no-op because, unless the `--reset-author` option is specified, `git commit --amend` ignores the user environment and reuses the authorship of the commit it amends. To make the code clearer and until we decide to use other authorships for squash commits than the one of the first commit, unwrap `git commit --amend`. Signed-off-by: Fabian Ruch baf...@gmail.com --- git-rebase--interactive.sh| 17 +++-- t/t3404-rebase-interactive.sh | 23 +++ 2 files changed, 30 insertions(+), 10 deletions(-) diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh index f8be238..ab807e5 100644 --- a/git-rebase--interactive.sh +++ b/git-rebase--interactive.sh @@ -622,9 +622,6 @@ do_next () { mark_action_done update_squash_messages $squash_style $sha1 - author_script_content=$(get_author_ident_from_commit HEAD) - echo $author_script_content $author_script - eval $author_script_content if ! pick_one -n $sha1 then git rev-parse --verify HEAD $amend @@ -634,7 +631,7 @@ do_next () { squash|s|fixup|f) # This is an intermediate commit; its message will only be # used in case of trouble. So use the long version: - do_with_author output git commit --allow-empty-message --allow-empty \ + output git commit --allow-empty-message --allow-empty \ --amend --no-verify -F $squash_msg \ ${gpg_sign_opt:+$gpg_sign_opt} || die_failed_squash $sha1 $rest @@ -643,14 +640,14 @@ do_next () { # This is the final command of this squash/fixup group if test -f $fixup_msg then - do_with_author output git commit --allow-empty-message --allow-empty \ + output git commit --allow-empty-message --allow-empty \ --amend --no-verify -F $fixup_msg \ ${gpg_sign_opt:+$gpg_sign_opt} || die_failed_squash $sha1 $rest else cp $squash_msg $GIT_DIR/SQUASH_MSG || exit rm -f $GIT_DIR/MERGE_MSG - do_with_author output git commit --allow-empty --amend --no-pre-commit -F $GIT_DIR/SQUASH_MSG -e \ + output git commit --allow-empty --amend --no-pre-commit -F $GIT_DIR/SQUASH_MSG -e \ ${gpg_sign_opt:+$gpg_sign_opt} || die_failed_squash $sha1 $rest fi @@ -939,7 +936,7 @@ continue) then : Nothing to commit -- skip this else - if ! test -f $author_script + if ! test -f $author_script ! test -f $amend then gpg_sign_opt_quoted=${gpg_sign_opt:+$(git rev-parse --sq-quote $gpg_sign_opt)} die You have staged changes in your working tree. If these changes are meant to be @@ -956,8 +953,6 @@ In both case, once you're done, continue with: git rebase --continue fi - . $author_script || - die Error trying to find the author identity to amend commit if test -f $amend then current_head=$(git rev-parse --verify HEAD) @@ -965,10 +960,12 @@ In both case, once you're done, continue with: die \ You have uncommitted changes in your working tree. Please, commit them first and then run 'git rebase --continue' again. - do_with_author git commit --amend
[PATCH v3 22/27] rebase -i: parse to-do list command line options
Read in to-do list lines as command args instead of command sha1 rest so that to-do list command lines can specify additional arguments apart from the commit hash and the log message title, which become the non-options in `args`. Loop over `args`, put all options (an argument beginning with a dash) in `opts`, stop the loop on the first non-option and assign it to `sha1`. For instance, the to-do list reword --signoff fa1afe1 Some change is parsed as `command=reword`, `opts= '--signoff'` (including the single quotes and the space for evaluation and concatenation of options), `sha1=fa1afel` and `rest=Some change`. The loop does not know the options it parses so that options that take an argument themselves are not supported at the moment. Neither are options that contain spaces because the shell expansion of `args` in `do_next` interprets white space characters as argument separator. Print an error message for unknown or unsupported command line options, which means an error for all specified options at the moment. Cleanly break the `do_next` loop by assigning a reason to the local variable `malformed`, which triggers the unknown command code in `do_replay`. Move the error code to the beginning of `do_replay` so that unknown commands are reported before bad options are as only the first error we come across is reported. For instance, the to-do list from above produces the error Unknown 'reword' option: --signoff Please fix this using 'git rebase --edit-todo'. The to-do list is also parsed when the commit hashes are translated between long and short format before and after the to-do list is edited. Apply the same procedure as in `do_replay` with the exception that we only care about where the options stop and the commit hash begins. Do not reject any options when transforming the commit hashes. Enable the specification of to-do list command line options in `FAKE_LINES` the same way this is accomplished for command lines passed to `exec`. Define a new `fake_editor.sh` that edits a static to-do list instead of the one passed as argument when invoked by git-rebase. Add a test case that checks that unknown options are refused and can be corrected using `--edit-todo`. Signed-off-by: Fabian Ruch baf...@gmail.com --- git-rebase--interactive.sh | 95 +++--- t/lib-rebase.sh| 20 - t/t3427-rebase-line-options.sh | 26 3 files changed, 114 insertions(+), 27 deletions(-) create mode 100755 t/t3427-rebase-line-options.sh diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh index e140bf0..8b39f2d 100644 --- a/git-rebase--interactive.sh +++ b/git-rebase--interactive.sh @@ -578,30 +578,71 @@ do_pick () { } do_replay () { + malformed= command=$1 - sha1=$2 - rest=$3 + shift + case $command in + pick|reword|edit|squash|fixup) + ;; + *) + read -r command $todo + malformed=Unknown command: $command + ;; + esac + + opts= + while test $# -gt 0 test -z $malformed + do + case $1 in + -*) + malformed=Unknown '$command' option: $1 + ;; + *) + break + ;; + esac + opts=$opts $1 + shift + done + sha1=$1 + shift + rest=$* + + if test -n $malformed + then + warn $malformed + fixtodo=Please fix this using 'git rebase --edit-todo'. + if git rev-parse --verify -q $sha1 /dev/null + then + die_with_patch $sha1 $fixtodo + else + die $fixtodo + fi + fi case $command in pick|p) comment_for_reflog pick mark_action_done - do_pick $sha1 || die_with_patch $sha1 Could not apply $sha1... $rest + do_pick $opts $sha1 \ + || die_with_patch $sha1 Could not apply $sha1... $rest record_in_rewritten $sha1 ;; reword|r) comment_for_reflog reword mark_action_done - do_pick --edit $sha1 || die_with_patch $sha1 Could not apply $sha1... $rest + do_pick --edit $opts $sha1 \ + || die_with_patch $sha1 Could not apply $sha1... $rest record_in_rewritten $sha1 ;; edit|e) comment_for_reflog edit mark_action_done - do_pick $sha1 || die_with_patch $sha1 Could not apply $sha1... $rest + do_pick $opts $sha1 \ + || die_with_patch $sha1 Could not apply $sha1... $rest warn Stopped at $sha1... $rest
[PATCH v3 15/27] rebase -i: do not die in do_pick
Since `do_pick` might be executed in a sub-shell (a modified author environment for instance), calling `die` in `do_pick` has no effect but exiting the sub-shell with a failure exit status. The git-rebase--interactive script is not terminated. Moreover, if `do_pick` is called while a squash or fixup is in effect, `die_with_patch` will discard `$squash_msg` as commit message. Lastly, after a `die` in `do_pick` `do_next` has no chance to reschedule tasks that failed before changes could be applied. Indicate an error in `do_pick` using return statements and properly kill the script at the call sites. Although possible in principle, the issued error messages are no more indicating whether `do_pick` failed while applying or while committing the changes. This reduces code complexity at the call site and does not matter from a user's point of view because a glance at the index reveals whether there are conflicts or not and in-depth troubleshooting is still possible using the `--verbose` option. Remove the commit message title argument from `do_pick`'s interface, which has become unused. Signed-off-by: Fabian Ruch baf...@gmail.com --- git-rebase--interactive.sh | 34 +++--- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh index 181e06a..a5a8aa3 100644 --- a/git-rebase--interactive.sh +++ b/git-rebase--interactive.sh @@ -464,7 +464,7 @@ record_in_rewritten() { # Apply the changes introduced by the given commit to the current head. # -# do_pick [--edit] commit title +# do_pick [--edit] commit # # Wrapper around git-cherry-pick. # @@ -476,9 +476,11 @@ record_in_rewritten() { # commit # The commit to cherry-pick. # -# title -# The commit message title of commit. Used for information -# purposes only. +# The return value is 1 if applying the changes resulted in a conflict +# and 2 if the specified arguments were incorrect. If the changes could +# be applied successfully but creating the commit failed, a value +# greater than 2 is returned. No commit is created in either case and +# the index is left with the (conflicting) changes in place. do_pick () { allow_empty_message=y rewrite= @@ -493,7 +495,8 @@ do_pick () { allow_empty_message= ;; -*) - die do_pick: unrecognized option -- $1 + warn do_pick: unrecognized option -- $1 + return 2 ;; *) break @@ -501,7 +504,11 @@ do_pick () { esac shift done - test $# -ne 2 die do_pick: wrong number of arguments + if test $# -ne 1 + then + warn do_pick: wrong number of arguments + return 2 + fi if test $(git rev-parse HEAD) = $squash_onto then @@ -519,11 +526,9 @@ do_pick () { # rebase --continue. git commit --allow-empty --allow-empty-message --amend \ --no-post-rewrite -n -q -C $1 - pick_one -n $1 || - die_with_patch $1 Could not apply $1... $2 + pick_one -n $1 || return 1 else - pick_one ${rewrite:+-n} $1 || - die_with_patch $1 Could not apply $1... $2 + pick_one ${rewrite:+-n} $1 || return 1 fi if test -n $rewrite @@ -534,8 +539,7 @@ do_pick () { ${allow_empty_message:+--allow-empty-message} \ ${rewrite_amend:+--amend} \ ${rewrite_edit:+--edit --commit-msg} \ - ${gpg_sign_opt:+$gpg_sign_opt} || - die_with_patch $1 Could not rewrite commit after successfully picking $1... $2 + ${gpg_sign_opt:+$gpg_sign_opt} || return 3 fi } @@ -550,21 +554,21 @@ do_next () { comment_for_reflog pick mark_action_done - do_pick $sha1 $rest + do_pick $sha1 || die_with_patch $sha1 Could not apply $sha1... $rest record_in_rewritten $sha1 ;; reword|r) comment_for_reflog reword mark_action_done - do_pick --edit $sha1 $rest + do_pick --edit $sha1 || die_with_patch $sha1 Could not apply $sha1... $rest record_in_rewritten $sha1 ;; edit|e) comment_for_reflog edit mark_action_done - do_pick $sha1 $rest + do_pick $sha1 || die_with_patch $sha1 Could not apply $sha1... $rest warn Stopped at $sha1... $rest exit_with_patch $sha1 0 ;; -- 2.0.1 -- To unsubscribe from this list: send the line unsubscribe
[PATCH v3 19/27] rebase -i: prepare for squash in terms of do_pick --amend
Rewrite `squash` and `fixup` handling in `do_next` using the sequence pick_one commit in order to test the correctness of a single `do_squash` or parameterised `do_pick` and make the subsequent patch reimplementing `squash` in terms of such a single function more readable. Do not call `rm -f $GIT_DIR/MERGE_MSG` since it has no effect on the state after git-rebase--interactive terminates. The option `-F` makes git-commit ignore `MERGE_MSG` for the log message. If git-commit succeeds, `MERGE_MSG` is removed, and if it fails, `MERGE_MSG` is overwritten by the error sequence `die_failed_squash`. In summary, removing `MERGE_MSG` neither influences the squash commit message nor the file state after git-commit returns. Moreover, `pick_one` ignores `$GIT_DIR/SQUASH_MSG` and does not touch `$squash_msg` so that it is correct to execute `pick_one` immediately before git-commit. Might be squashed into the subsequent commit. Signed-off-by: Fabian Ruch baf...@gmail.com --- git-rebase--interactive.sh | 21 +++-- 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh index ab807e5..614579c 100644 --- a/git-rebase--interactive.sh +++ b/git-rebase--interactive.sh @@ -622,15 +622,15 @@ do_next () { mark_action_done update_squash_messages $squash_style $sha1 - if ! pick_one -n $sha1 - then - git rev-parse --verify HEAD $amend - die_failed_squash $sha1 $rest - fi case $(peek_next_command) in squash|s|fixup|f) # This is an intermediate commit; its message will only be # used in case of trouble. So use the long version: + if ! pick_one -n $sha1 + then + git rev-parse --verify HEAD $amend + die_failed_squash $sha1 Could not apply $sha1... $rest + fi output git commit --allow-empty-message --allow-empty \ --amend --no-verify -F $squash_msg \ ${gpg_sign_opt:+$gpg_sign_opt} || @@ -640,13 +640,22 @@ do_next () { # This is the final command of this squash/fixup group if test -f $fixup_msg then + if ! pick_one -n $sha1 + then + git rev-parse --verify HEAD $amend + die_failed_squash $sha1 Could not apply $sha1... $rest + fi output git commit --allow-empty-message --allow-empty \ --amend --no-verify -F $fixup_msg \ ${gpg_sign_opt:+$gpg_sign_opt} || die_failed_squash $sha1 $rest else cp $squash_msg $GIT_DIR/SQUASH_MSG || exit - rm -f $GIT_DIR/MERGE_MSG + if ! pick_one -n $sha1 + then + git rev-parse --verify HEAD $amend + die_failed_squash $sha1 Could not apply $sha1... $rest + fi output git commit --allow-empty --amend --no-pre-commit -F $GIT_DIR/SQUASH_MSG -e \ ${gpg_sign_opt:+$gpg_sign_opt} || die_failed_squash $sha1 $rest -- 2.0.1 -- To unsubscribe from this list: send the line unsubscribe git in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 17/27] rebase -i: teach do_pick the option --file
`do_pick` is the git-cherry-pick wrapper in git-rebase--interactive that is used to implement the to-do list command `pick`, `reword` and `edit`. To cater for the different pick behaviours (like `squash`), `do_pick` accepts several options not only from the git-cherry-pick but also the git-commit interface. Add the option `--file` from the git-commit interface to the options pool of `do_pick`. It expects an argument itself which is interpreted as a file path and takes the commit message from the given file. If `--file` is passed to `do_pick`, assign the given file path to the local variable `rewrite_message` and relay the option --file $rewrite_message to the git-commit command line which creates the commit. Signed-off-by: Fabian Ruch baf...@gmail.com --- git-rebase--interactive.sh | 20 +++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh index 20a637a..f8be238 100644 --- a/git-rebase--interactive.sh +++ b/git-rebase--interactive.sh @@ -464,7 +464,7 @@ record_in_rewritten() { # Apply the changes introduced by the given commit to the current head. # -# do_pick [--amend] [--edit] commit +# do_pick [--amend] [--file file] [--edit] commit # # Wrapper around git-cherry-pick. # @@ -474,6 +474,12 @@ record_in_rewritten() { # # _This is not a git-cherry-pick option._ # +# -F file, --file file +# Take the commit message from the given file. This creates a fresh +# commit. +# +# _This is not a git-cherry-pick option._ +# # -e, --edit # After picking commit, open an editor and let the user edit the # commit message. The editor contents becomes the commit message of @@ -492,6 +498,7 @@ do_pick () { rewrite= rewrite_amend= rewrite_edit= + rewrite_message= while test $# -gt 0 do case $1 in @@ -505,6 +512,16 @@ do_pick () { rewrite_amend=y git rev-parse --verify HEAD $amend ;; + -F|--file) + if test $# -eq 0 + then + warn do_pick: option --file specified but no file given + return 2 + fi + rewrite=y + rewrite_message=$2 + shift + ;; -e|--edit) rewrite=y rewrite_edit=y @@ -555,6 +572,7 @@ do_pick () { ${allow_empty_message:+--allow-empty-message} \ ${rewrite_amend:+--amend} \ ${rewrite_edit:+--edit --commit-msg} \ + ${rewrite_message:+--file $rewrite_message} \ ${gpg_sign_opt:+$gpg_sign_opt} || return 3 fi } -- 2.0.1 -- To unsubscribe from this list: send the line unsubscribe git in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 21/27] rebase -i: explicitly distinguish replay commands and exec tasks
There are two kinds of to-do list commands available. One kind replays a commit (`pick`, `reword`, `edit`, `squash` and `fixup` that is) and the other executes a shell command (`exec`). We will call the first kind replay commands. The two kinds of tasks are scheduled using different line formats. Replay commands expect a commit hash argument following the command name and exec concatenates all arguments to assemble a command line. Adhere to the distinction of formats by not trying to parse the `sha1` field unless we are dealing with a replay command. Move the replay command handling code to a new function `do_replay` which assumes the first argument to be a commit hash and make no more such assumptions in `do_next`. Signed-off-by: Fabian Ruch baf...@gmail.com --- git-rebase--interactive.sh | 42 -- 1 file changed, 28 insertions(+), 14 deletions(-) diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh index 6a123f0..e140bf0 100644 --- a/git-rebase--interactive.sh +++ b/git-rebase--interactive.sh @@ -577,13 +577,12 @@ do_pick () { fi } -do_next () { - rm -f $msg $author_script $amend || exit - read -r command sha1 rest $todo +do_replay () { + command=$1 + sha1=$2 + rest=$3 + case $command in - $comment_char*|''|noop) - mark_action_done - ;; pick|p) comment_for_reflog pick @@ -659,6 +658,28 @@ do_next () { esac record_in_rewritten $sha1 ;; + *) + read -r command $todo + warn Unknown command: $command + fixtodo=Please fix this using 'git rebase --edit-todo'. + if git rev-parse --verify -q $sha1 /dev/null + then + die_with_patch $sha1 $fixtodo + else + die $fixtodo + fi + ;; + esac +} + +do_next () { + rm -f $msg $author_script $amend || exit + read -r command sha1 rest $todo + + case $command in + $comment_char*|''|noop) + mark_action_done + ;; x|exec) read -r command rest $todo mark_action_done @@ -698,14 +719,7 @@ do_next () { fi ;; *) - warn Unknown command: $command $sha1 $rest - fixtodo=Please fix this using 'git rebase --edit-todo'. - if git rev-parse --verify -q $sha1 /dev/null - then - die_with_patch $sha1 $fixtodo - else - die $fixtodo - fi + do_replay $command $sha1 $rest ;; esac test -s $todo return -- 2.0.1 -- To unsubscribe from this list: send the line unsubscribe git in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 13/27] rebase -i: do not use -C when --no-edit is sufficient
The command line used to recreate root commits uses `-C` to suppress the log message editor. This is unnecessarily confusing, though, because that suppression is a secondary effect of the option. The main purpose of `-C` is to pull the metadata from another commit, but here we know that this is a no-op, since we are amending a commit just created from the same data. At the time `-C` was introduced, git-commit did not yet have a documented `--no-edit`, and this was a reasonable way to get the desired behavior. Switch it to use `--no-edit` to make the intended effect more obvious. Signed-off-by: Fabian Ruch baf...@gmail.com --- git-rebase--interactive.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh index f4bb822..6561831 100644 --- a/git-rebase--interactive.sh +++ b/git-rebase--interactive.sh @@ -511,7 +511,7 @@ do_pick () { --no-post-rewrite -n -q -C $1 pick_one -n $1 output git commit --allow-empty --allow-empty-message \ - --amend --no-post-rewrite -n -C $1 \ + --amend --no-post-rewrite -n --no-edit \ ${gpg_sign_opt:+$gpg_sign_opt} || die_with_patch $1 Could not apply $1... $2 else -- 2.0.1 -- To unsubscribe from this list: send the line unsubscribe git in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 11/27] rebase -i: implement reword in terms of do_pick
The to-do list command `reword` replays a commit like `pick` but lets the user also edit the commit's log message. If one thinks of `pick` entries as scheduled `cherry-pick` command lines, then `reword` becomes an alias for the command line `cherry-pick --edit`. The porcelain `rebase--interactive` defines a function `do_pick` for processing the `pick` entries on to-do lists. Reimplement `reword` in terms of `do_pick --edit`. If the user picks a commit using the to-do list line reword fa1afe1 Some change execute the command `do_pick --edit fa1afe1 Some change` which carries out exactly the same steps as the case arm for `reword` in `do_next` so far. Signed-off-by: Fabian Ruch baf...@gmail.com --- git-rebase--interactive.sh | 6 +- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh index 8a89ced..2d768b3 100644 --- a/git-rebase--interactive.sh +++ b/git-rebase--interactive.sh @@ -546,11 +546,7 @@ do_next () { comment_for_reflog reword mark_action_done - do_pick $sha1 $rest - output git commit --allow-empty --amend --no-post-rewrite --no-pre-commit ${gpg_sign_opt:+$gpg_sign_opt} || { - warn Could not amend commit after successfully picking $sha1... $rest - exit_with_patch $sha1 1 - } + do_pick --edit $sha1 $rest record_in_rewritten $sha1 ;; edit|e) -- 2.0.1 -- To unsubscribe from this list: send the line unsubscribe git in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 14/27] rebase -i: commit only once when rewriting picks
The options passed to `do_pick` determine whether the picked commit will be rewritten or not. If the commit gets rewritten, because the user requested to edit the commit message for instance, let `pick_one` merely apply the changes introduced by the commit and do not commit the resulting tree yet. If the commit is replayed as is, leave it to `pick_one` to recreate the commit (possibly by fast-forwarding the head). This makes it easier to combine git-commit options like `--edit` and `--amend` in `do_pick` because git-cherry-pick does not support `--amend`. In the case of `--edit`, do not `exit_with_patch` but assign `rewrite` to pick the changes with `-n`. If the pick conflicts, no commit is created which we would have to amend when continuing the rebase. To complete the pick after the conflicts are resolved the user just resumes with `git rebase --continue`. git-commit lets the user edit the commit log message by default. We do not want that for the rewriting git-commit command line because the default behaviour of git-rebase is exactly the opposite. Pass `--no-edit` when rewriting a picked commit. An explicit `--edit` passed to `do_pick` (for instance, when reword is executed) enables the editor launch again. Similarly, pass `--allow-empty-message` unless the log message is edited. If `rebase--interactive` is used to rebase a complete branch onto some head, `rebase` creates a sentinel commit that requires special treatment by `do_pick`. Do not finalize the pick here either because its commit message can be altered as for any other pick. Since the orphaned root commit gets a temporary parent, it is always rewritten. Safely use the rewrite infrastructure of `do_pick` to create the final commit. Signed-off-by: Fabian Ruch baf...@gmail.com --- git-rebase--interactive.sh| 41 ++--- t/t3404-rebase-interactive.sh | 10 ++ 2 files changed, 36 insertions(+), 15 deletions(-) diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh index 6561831..181e06a 100644 --- a/git-rebase--interactive.sh +++ b/git-rebase--interactive.sh @@ -63,9 +63,10 @@ msgnum=$state_dir/msgnum author_script=$state_dir/author-script # When an edit rebase command is being processed, the SHA1 of the -# commit to be edited is recorded in this file. When git rebase -# --continue is executed, if there are any staged changes then they -# will be amended to the HEAD commit, but only provided the HEAD +# commit to be edited is recorded in this file. The same happens when +# rewriting a root commit fails, for instance reword. When git +# rebase --continue is executed, if there are any staged changes then +# they will be amended to the HEAD commit, but only provided the HEAD # commit is still the commit to be edited. When any other rebase # command is processed, this file is deleted. amend=$state_dir/amend @@ -479,12 +480,17 @@ record_in_rewritten() { # The commit message title of commit. Used for information # purposes only. do_pick () { - edit= + allow_empty_message=y + rewrite= + rewrite_amend= + rewrite_edit= while test $# -gt 0 do case $1 in -e|--edit) - edit=y + rewrite=y + rewrite_edit=y + allow_empty_message= ;; -*) die do_pick: unrecognized option -- $1 @@ -499,6 +505,10 @@ do_pick () { if test $(git rev-parse HEAD) = $squash_onto then + rewrite=y + rewrite_amend=y + git rev-parse --verify HEAD $amend + # Set the correct commit message and author info on the # sentinel root before cherry-picking the original changes # without committing (-n). Finally, update the sentinel again @@ -509,22 +519,23 @@ do_pick () { # rebase --continue. git commit --allow-empty --allow-empty-message --amend \ --no-post-rewrite -n -q -C $1 - pick_one -n $1 - output git commit --allow-empty --allow-empty-message \ - --amend --no-post-rewrite -n --no-edit \ - ${gpg_sign_opt:+$gpg_sign_opt} || + pick_one -n $1 || die_with_patch $1 Could not apply $1... $2 else - pick_one $1 || + pick_one ${rewrite:+-n} $1 || die_with_patch $1 Could not apply $1... $2 fi - if test -n $edit + if test -n $rewrite then - output git commit --allow-empty --amend --no-post-rewrite --no-pre-commit ${gpg_sign_opt:+$gpg_sign_opt} || { - warn Could not amend commit after successfully picking $1... $2 -
[PATCH v3 20/27] rebase -i: implement squash in terms of do_pick
The to-do list command `squash` and its close relative `fixup` replay the changes of a commit like `pick` but do not recreate the commit. Instead they replace the previous commit with a new commit that also introduces the changes of the squashed commit. This is roughly like cherry-picking without committing and using git-commit to amend the previous commit. The to-do list pick a Some changes squash b Some more changes gets translated into the sequence of git commands git cherry-pick a git cherry-pick -n b git commit --amend and if git-cherry-pick supported `--amend` this would look even more like the to-do list it is based on git cherry-pick a git cherry-pick --amend b. Since `do_pick` takes care of `pick` entries and the above suggests `squash` as an alias for `pick --amend`, reimplement `squash` in terms of `do_pick --amend`. Introduce `$squash_msg` as the commit message via the `--file` option. When the last commit of a squash series is processed, the user is asked to review the log message. Pass `--edit` as additional option in this case. The only difference in the options passed to git-commit and `do_pick` is the omitted `--no-verify`. However, `do_pick` does not execute the verification hooks anyway because it solely replays commits and assumes that they have been verified before. Signed-off-by: Fabian Ruch baf...@gmail.com --- git-rebase--interactive.sh | 32 ++-- 1 file changed, 6 insertions(+), 26 deletions(-) diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh index 614579c..6a123f0 100644 --- a/git-rebase--interactive.sh +++ b/git-rebase--interactive.sh @@ -626,39 +626,19 @@ do_next () { squash|s|fixup|f) # This is an intermediate commit; its message will only be # used in case of trouble. So use the long version: - if ! pick_one -n $sha1 - then - git rev-parse --verify HEAD $amend - die_failed_squash $sha1 Could not apply $sha1... $rest - fi - output git commit --allow-empty-message --allow-empty \ - --amend --no-verify -F $squash_msg \ - ${gpg_sign_opt:+$gpg_sign_opt} || - die_failed_squash $sha1 $rest + do_pick --amend -F $squash_msg $sha1 \ + || die_failed_squash $sha1 $rest ;; *) # This is the final command of this squash/fixup group if test -f $fixup_msg then - if ! pick_one -n $sha1 - then - git rev-parse --verify HEAD $amend - die_failed_squash $sha1 Could not apply $sha1... $rest - fi - output git commit --allow-empty-message --allow-empty \ - --amend --no-verify -F $fixup_msg \ - ${gpg_sign_opt:+$gpg_sign_opt} || - die_failed_squash $sha1 $rest + do_pick --amend -F $fixup_msg $sha1 \ + || die_failed_squash $sha1 $rest else cp $squash_msg $GIT_DIR/SQUASH_MSG || exit - if ! pick_one -n $sha1 - then - git rev-parse --verify HEAD $amend - die_failed_squash $sha1 Could not apply $sha1... $rest - fi - output git commit --allow-empty --amend --no-pre-commit -F $GIT_DIR/SQUASH_MSG -e \ - ${gpg_sign_opt:+$gpg_sign_opt} || - die_failed_squash $sha1 $rest + do_pick --amend -F $GIT_DIR/SQUASH_MSG -e $sha1 \ + || die_failed_squash $sha1 $rest fi rm -f $squash_msg $fixup_msg if test -z $keep_empty is_empty_commit HEAD -- 2.0.1 -- To unsubscribe from this list: send the line unsubscribe git in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 10/27] rebase -i: teach do_pick the option --edit
`do_pick` is the git-cherry-pick wrapper in git-rebase--interactive that is used to implement the to-do list command `pick`. To cater for the different pick behaviours (like `reword`), `do_pick` accepts several options not only from the git-cherry-pick but also the git-commit interface. Add the common option `--edit` to let the user edit the log message of the named commit. Loop over `$@` to parse the `do_pick` arguments. Assign the local variable `edit` if one of the options is `--edit` so that the remainder of `do_pick` can easily check whether the client code asked to edit the commit message. If one of the options is unknown, mention it on the console and `die`. Break the loop on the first non-option and do some sanity checking to ensure that there exactly two non-options, which are interpreted by the remainder as `commit` and `title` like before. `do_pick` ought to act as a wrapper around `cherry-pick`. Unfortunately, it cannot just forward `--edit` to the `cherry-pick` command line. The assembled command line is executed within a command substitution for controlling the verbosity of `rebase--interactive`. Passing `--edit` would either hang the terminal or clutter the substituted command output with control sequences. Execute the `reword` code from `do_next` instead if the option `--edit` is specified. Signed-off-by: Fabian Ruch baf...@gmail.com --- git-rebase--interactive.sh | 43 +++ 1 file changed, 43 insertions(+) diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh index 570c4e9..8a89ced 100644 --- a/git-rebase--interactive.sh +++ b/git-rebase--interactive.sh @@ -461,7 +461,42 @@ record_in_rewritten() { esac } +# Apply the changes introduced by the given commit to the current head. +# +# do_pick [--edit] commit title +# +# Wrapper around git-cherry-pick. +# +# -e, --edit +# After picking commit, open an editor and let the user edit the +# commit message. The editor contents becomes the commit message of +# the new head. This creates a fresh commit. +# +# commit +# The commit to cherry-pick. +# +# title +# The commit message title of commit. Used for information +# purposes only. do_pick () { + edit= + while test $# -gt 0 + do + case $1 in + -e|--edit) + edit=y + ;; + -*) + die do_pick: unrecognized option -- $1 + ;; + *) + break + ;; + esac + shift + done + test $# -ne 2 die do_pick: wrong number of arguments + if test $(git rev-parse HEAD) = $squash_onto then # Set the correct commit message and author info on the @@ -483,6 +518,14 @@ do_pick () { pick_one $1 || die_with_patch $1 Could not apply $1... $2 fi + + if test -n $edit + then + output git commit --allow-empty --amend --no-post-rewrite --no-pre-commit ${gpg_sign_opt:+$gpg_sign_opt} || { + warn Could not amend commit after successfully picking $1... $2 + exit_with_patch $1 1 + } + fi } do_next () { -- 2.0.1 -- To unsubscribe from this list: send the line unsubscribe git in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 12/27] rebase -i: log the replay of root commits
The command line used to recreate root commits specifies the option `-q` which suppresses the commit summary message. However, git-rebase--interactive tends to tell the user about the commits it creates in the final history, if she wishes (cf. command line option `--verbose`). The code parts handling non-root commits and squash commits all output commit summary messages. Do not make the replay of root commits an exception. Remove the option to make the report of the rebased history complete. Do not forget to wrap the git-commit command line in `output` so that the summary is shown if git-rebase is called with the `--verbose` option but suppressed otherwise. It is OK that the commit summary is still suppressed when git-commit is used to initialize the authorship of the sentinel commit because this additional commit is an implementation detail hidden from the final history. The removed `-q` option was probably introduced as a copy-and-paste error stemming from that part of the root commit handling code. Signed-off-by: Fabian Ruch baf...@gmail.com --- git-rebase--interactive.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh index 2d768b3..f4bb822 100644 --- a/git-rebase--interactive.sh +++ b/git-rebase--interactive.sh @@ -510,8 +510,8 @@ do_pick () { git commit --allow-empty --allow-empty-message --amend \ --no-post-rewrite -n -q -C $1 pick_one -n $1 - git commit --allow-empty --allow-empty-message \ - --amend --no-post-rewrite -n -q -C $1 \ + output git commit --allow-empty --allow-empty-message \ + --amend --no-post-rewrite -n -C $1 \ ${gpg_sign_opt:+$gpg_sign_opt} || die_with_patch $1 Could not apply $1... $2 else -- 2.0.1 -- 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
[BUG] Hang when I did something a bit weird with submodules
Hi, I was just setting up a new project using submodules and have run into what appears to be a hang when git status is invoked. I haven't tried to reproduce this but this is basically what I did (edited highlights from my bash_history). $ git --version git version 2.0.3 $ mkdir proj $ cd proj $ git init $ git submodule add internal-repo-with-build-scripts build $ git submodule add --reference ~/src/linux/.git git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git linux # I'm not sure if the --reference is relevant but I was just wanting to cut down on my network transfer $ git submodule add internal-repo-with-skeleton-fs rootfs Oops I really wanted linux-stable to get the same version my board vendor is using $ vim .gitmodules # change to linux-stable $ git submodule sync I'm not sure if this is a valid use-case but nothing complained that I was changing the URL. In theory linux-stable should be a super-set of linus' tree so the repositories are basically equivalent. $ cd linux/ $ git remote show origin * remote origin Fetch URL: git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git # Seems to have done the trick $ git reset --hard v3.4.69 I suspect this is where the problem starts. When I did the git submodule add it was pointing at the tip of linus' tree. Now I have rewound considerably. $ git status [hang] For what it's worth here's the output when I run with GIT_TRACE=1 git status trace: built-in: git 'status' trace: run_command: 'status' '--porcelain' trace: exec: 'git' 'status' '--porcelain' trace: built-in: git 'status' '--porcelain' trace: run_command: 'status' '--porcelain' trace: exec: 'git' 'status' '--porcelain' trace: built-in: git 'status' '--porcelain' trace: run_command: 'status' '--porcelain' trace: exec: 'git' 'status' '--porcelain' trace: built-in: git 'status' '--porcelain' On branch master Initial commit Changes to be committed: (use git rm --cached file... to unstage) new file: .gitmodules new file: rootfs new file: build new file: linux Changes not staged for commit: (use git add file... to update what will be committed) (use git checkout -- file... to discard changes in working directory) modified: .gitmodules modified: linux (new commits) trace: run_command: 'submodule' 'summary' '--cached' '--for-status' '--summary-limit' '-1' 'HEAD' trace: exec: 'git' 'submodule' 'summary' '--cached' '--for-status' '--summary-limit' '-1' 'HEAD' trace: exec: 'git-submodule' 'summary' '--cached' '--for-status' '--summary-limit' '-1' 'HEAD' trace: run_command: 'git-submodule' 'summary' '--cached' '--for-status' '--summary-limit' '-1' 'HEAD' trace: built-in: git 'rev-parse' '--git-dir' trace: built-in: git 'rev-parse' '-q' '--git-dir' trace: built-in: git 'rev-parse' '--show-prefix' trace: built-in: git 'rev-parse' '--show-toplevel' trace: built-in: git 'rev-parse' '-q' '--verify' '--default' 'HEAD' 'HEAD' trace: built-in: git 'hash-object' '-w' '-t' 'tree' '--stdin' trace: built-in: git 'rev-parse' '--show-toplevel' trace: built-in: git 'rev-parse' '--sq' '--prefix' '' '--' trace: built-in: git 'diff-index' '--cached' '--ignore-submodules=dirty' '--raw' '4b825dc642cb6eb9a060e54bf8d69288fbee4904' '--' trace: built-in: git 'config' '-f' '.gitmodules' '--get-regexp' '^submodule\..*\.path$' trace: built-in: git 'config' 'submodule.rootfs.ignore' trace: built-in: git 'config' '-f' '.gitmodules' 'submodule.rootfs.ignore' trace: built-in: git 'config' '-f' '.gitmodules' '--get-regexp' '^submodule\..*\.path$' trace: built-in: git 'config' 'submodule.build.ignore' trace: built-in: git 'config' '-f' '.gitmodules' 'submodule.build.ignore' trace: built-in: git 'config' '-f' '.gitmodules' '--get-regexp' '^submodule\..*\.path$' trace: built-in: git 'config' 'submodule.linux.ignore' trace: built-in: git 'config' '-f' '.gitmodules' 'submodule.linux.ignore' trace: built-in: git 'diff-index' '--cached' '--ignore-submodules=dirty' '--raw' '4b825dc642cb6eb9a060e54bf8d69288fbee4904' '--' 'rootfs' 'build' 'linux' trace: built-in: git 'rev-parse' '-q' '--verify' 'e4bbdf3b45828a2e9ca37ef329b8e708e324dfb1^0' trace: built-in: git 'rev-list' '--first-parent' 'e4bbdf3b45828a2e9ca37ef329b8e708e324dfb1' '--' trace: built-in: git 'log' '--pretty=format: %s' '-1' 'e4bbdf3b45828a2e9ca37ef329b8e708e324dfb1' trace: built-in: git 'rev-parse' '-q' '--verify' '9f2d1659df78ea51eaa9ad5e7af9271996ac2a4c^0' trace: built-in: git 'rev-list' '--first-parent' '9f2d1659df78ea51eaa9ad5e7af9271996ac2a4c' '--' trace: built-in: git 'log' '--pretty=format: %s' '-1' '9f2d1659df78ea51eaa9ad5e7af9271996ac2a4c' trace: built-in: git 'rev-parse' '-q' '--verify' '7d1311b93e58ed55f3a31cc8f94c4b8fe988a2b9^0' trace: built-in: git 'rev-list' '--first-parent' '7d1311b93e58ed55f3a31cc8f94c4b8fe988a2b9' '--' trace: built-in: git 'log' '--pretty=format: %s' '-1' '7d1311b93e58ed55f3a31cc8f94c4b8fe988a2b9' Submodule changes to be
Re: [BUG] Hang when I did something a bit weird with submodules
On Tue, Aug 19, 2014 at 4:33 PM, Chris Packham judge.pack...@gmail.com wrote: Hi, I was just setting up a new project using submodules and have run into what appears to be a hang when git status is invoked. I haven't tried to reproduce this but this is basically what I did (edited highlights from my bash_history). $ git --version git version 2.0.3 $ mkdir proj $ cd proj $ git init $ git submodule add internal-repo-with-build-scripts build $ git submodule add --reference ~/src/linux/.git git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git linux # I'm not sure if the --reference is relevant but I was just wanting to cut down on my network transfer $ git submodule add internal-repo-with-skeleton-fs rootfs Oops I really wanted linux-stable to get the same version my board vendor is using $ vim .gitmodules # change to linux-stable $ git submodule sync I'm not sure if this is a valid use-case but nothing complained that I was changing the URL. In theory linux-stable should be a super-set of linus' tree so the repositories are basically equivalent. $ cd linux/ $ git remote show origin * remote origin Fetch URL: git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git # Seems to have done the trick $ git reset --hard v3.4.69 I suspect this is where the problem starts. When I did the git submodule add it was pointing at the tip of linus' tree. Now I have rewound considerably. $ git status [hang] For what it's worth here's the output when I run with GIT_TRACE=1 git status trace: built-in: git 'status' trace: run_command: 'status' '--porcelain' trace: exec: 'git' 'status' '--porcelain' trace: built-in: git 'status' '--porcelain' trace: run_command: 'status' '--porcelain' trace: exec: 'git' 'status' '--porcelain' trace: built-in: git 'status' '--porcelain' trace: run_command: 'status' '--porcelain' trace: exec: 'git' 'status' '--porcelain' trace: built-in: git 'status' '--porcelain' On branch master Initial commit Changes to be committed: (use git rm --cached file... to unstage) new file: .gitmodules new file: rootfs new file: build new file: linux Changes not staged for commit: (use git add file... to update what will be committed) (use git checkout -- file... to discard changes in working directory) modified: .gitmodules modified: linux (new commits) trace: run_command: 'submodule' 'summary' '--cached' '--for-status' '--summary-limit' '-1' 'HEAD' trace: exec: 'git' 'submodule' 'summary' '--cached' '--for-status' '--summary-limit' '-1' 'HEAD' trace: exec: 'git-submodule' 'summary' '--cached' '--for-status' '--summary-limit' '-1' 'HEAD' trace: run_command: 'git-submodule' 'summary' '--cached' '--for-status' '--summary-limit' '-1' 'HEAD' trace: built-in: git 'rev-parse' '--git-dir' trace: built-in: git 'rev-parse' '-q' '--git-dir' trace: built-in: git 'rev-parse' '--show-prefix' trace: built-in: git 'rev-parse' '--show-toplevel' trace: built-in: git 'rev-parse' '-q' '--verify' '--default' 'HEAD' 'HEAD' trace: built-in: git 'hash-object' '-w' '-t' 'tree' '--stdin' trace: built-in: git 'rev-parse' '--show-toplevel' trace: built-in: git 'rev-parse' '--sq' '--prefix' '' '--' trace: built-in: git 'diff-index' '--cached' '--ignore-submodules=dirty' '--raw' '4b825dc642cb6eb9a060e54bf8d69288fbee4904' '--' trace: built-in: git 'config' '-f' '.gitmodules' '--get-regexp' '^submodule\..*\.path$' trace: built-in: git 'config' 'submodule.rootfs.ignore' trace: built-in: git 'config' '-f' '.gitmodules' 'submodule.rootfs.ignore' trace: built-in: git 'config' '-f' '.gitmodules' '--get-regexp' '^submodule\..*\.path$' trace: built-in: git 'config' 'submodule.build.ignore' trace: built-in: git 'config' '-f' '.gitmodules' 'submodule.build.ignore' trace: built-in: git 'config' '-f' '.gitmodules' '--get-regexp' '^submodule\..*\.path$' trace: built-in: git 'config' 'submodule.linux.ignore' trace: built-in: git 'config' '-f' '.gitmodules' 'submodule.linux.ignore' trace: built-in: git 'diff-index' '--cached' '--ignore-submodules=dirty' '--raw' '4b825dc642cb6eb9a060e54bf8d69288fbee4904' '--' 'rootfs' 'build' 'linux' trace: built-in: git 'rev-parse' '-q' '--verify' 'e4bbdf3b45828a2e9ca37ef329b8e708e324dfb1^0' trace: built-in: git 'rev-list' '--first-parent' 'e4bbdf3b45828a2e9ca37ef329b8e708e324dfb1' '--' trace: built-in: git 'log' '--pretty=format: %s' '-1' 'e4bbdf3b45828a2e9ca37ef329b8e708e324dfb1' trace: built-in: git 'rev-parse' '-q' '--verify' '9f2d1659df78ea51eaa9ad5e7af9271996ac2a4c^0' trace: built-in: git 'rev-list' '--first-parent' '9f2d1659df78ea51eaa9ad5e7af9271996ac2a4c' '--' trace: built-in: git 'log' '--pretty=format: %s' '-1' '9f2d1659df78ea51eaa9ad5e7af9271996ac2a4c' trace: built-in: git 'rev-parse' '-q' '--verify' '7d1311b93e58ed55f3a31cc8f94c4b8fe988a2b9^0' trace: built-in: git 'rev-list'
Re: [PATCH] make config --add behave correctly for empty and NULL values
On Mon, Aug 18, 2014 at 11:18:52AM -0700, Junio C Hamano wrote: Are we sure that a^, which cannot be true for any string, will not be caught by anybody's regcomp() as an error? I know regcomp() accepts the expression and regexec() fails to match with GNU libc, but that is not the whole of the world. We do support negation (ourselves) in the regexp, so !$foo would work, where $foo is some regexp that always matches. But that may be digging ourselves the opposite hole, trying to find a pattern that reliably matches everything. To be honest, I'd rather see this done right, by giving an option to the caller to tell the function not to call regcomp/regexec in matches(). Yeah, that was my first thought, too on seeing the patch. I even worked up an example before reading your message, but: * Define a global exported via cache.h and defined in config.c extern const char CONFIG_SET_MULTIVAR_NO_REPLACE[]; and pass it from this calling site, instead of an arbitrary literal string e.g. a^ * Add a bit to the store struct, e.g. unsigned value_never_matches:1; * In git_config_set_multivar_in_file() implementation, check for this constant address and set store.value_never_matches to true; * in matches(), check this bit and always return No, this existing value do not match when it is set. I just used #define CONFIG_REGEX_NONE ((void *)1) as my magic sentinel value, both for the string and compiled regex versions. Adding a bit to the store struct is a lot less disgusting and error-prone. So I won't share mine here. :) -Peff -- 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