Re: [PATCH] Documentation/git-rebase.txt: fix -f description to match actual git behavior.

2014-08-18 Thread Sergey Organov
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

2014-08-18 Thread Tanay Abhra
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

2014-08-18 Thread Dickson, Alex
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

2014-08-18 Thread Sokolov, Konstantin (ext)
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

2014-08-18 Thread Matthieu Moy
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

2014-08-18 Thread Tidwell, James



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.

2014-08-18 Thread Sergey Organov
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

2014-08-18 Thread Robin Rosenberg


- 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

2014-08-18 Thread Erik Faye-Lund
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

2014-08-18 Thread Dickson, Alex
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

2014-08-18 Thread Daniel Corbe

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

2014-08-18 Thread Erik Faye-Lund
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

2014-08-18 Thread Erik Faye-Lund
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.

2014-08-18 Thread Junio C Hamano
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

2014-08-18 Thread Junio C Hamano
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

2014-08-18 Thread Daniel Corbe

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

2014-08-18 Thread Junio C Hamano
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

2014-08-18 Thread Junio C Hamano
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

2014-08-18 Thread Junio C Hamano
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

2014-08-18 Thread 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.
--
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

2014-08-18 Thread Daniel Corbe
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

2014-08-18 Thread Bernhard Reiter
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

2014-08-18 Thread Jaime Soriano Pastor
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

2014-08-18 Thread Erik Faye-Lund
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

2014-08-18 Thread Junio C Hamano
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

2014-08-18 Thread Robert Dailey
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.

2014-08-18 Thread Torsten Bögershausen
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

2014-08-18 Thread Jonathan Nieder
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

2014-08-18 Thread Fabian Ruch
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

2014-08-18 Thread Fabian Ruch
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

2014-08-18 Thread Fabian Ruch
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

2014-08-18 Thread Fabian Ruch
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

2014-08-18 Thread Fabian Ruch
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

2014-08-18 Thread Fabian Ruch
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

2014-08-18 Thread Fabian Ruch
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

2014-08-18 Thread Fabian Ruch
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

2014-08-18 Thread Fabian Ruch
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

2014-08-18 Thread Fabian Ruch
`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

2014-08-18 Thread Fabian Ruch
`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

2014-08-18 Thread Fabian Ruch
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

2014-08-18 Thread Fabian Ruch
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

2014-08-18 Thread Fabian Ruch
`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

2014-08-18 Thread Fabian Ruch
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

2014-08-18 Thread Fabian Ruch
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

2014-08-18 Thread Fabian Ruch
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

2014-08-18 Thread Fabian Ruch
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

2014-08-18 Thread Fabian Ruch
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

2014-08-18 Thread Fabian Ruch
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

2014-08-18 Thread Fabian Ruch
`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

2014-08-18 Thread Fabian Ruch
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

2014-08-18 Thread Fabian Ruch
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

2014-08-18 Thread Fabian Ruch
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

2014-08-18 Thread Fabian Ruch
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

2014-08-18 Thread Fabian Ruch
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

2014-08-18 Thread Fabian Ruch
`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

2014-08-18 Thread Fabian Ruch
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

2014-08-18 Thread Chris Packham
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

2014-08-18 Thread Chris Packham
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

2014-08-18 Thread Jeff King
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