Re: [RFC] git checkout $tree -- $path always rewrites files

2014-11-08 Thread Martin von Zweigbergk
First of all, thanks again for spending time on this.

On Sat, Nov 8, 2014 at 12:30 AM, Jeff King  wrote:
> On Fri, Nov 07, 2014 at 11:35:59PM -0800, Junio C Hamano wrote:
>
> So just to be clear, the behavior we want is that:
>
>   echo foo >some-new-path
>   git add some-new-path
>   git checkout HEAD -- .
>
> will delete some-new-path (whereas the current code turns it into an
> untracked file).

Yes, I think that's what I would expect.

> What should:
>
>   git checkout HEAD -- some-new-path
>
> do in that case? With the current code, it actually barfs, complaining
> that nothing matched some-new-path (because it is not part of HEAD, and
> therefore we don't consider it at all), and aborts the whole operation.
> I think we would want to delete some-new-path in that case, too.

I don't think we'd want it to be deleted. I would view 'git reset
--hard' as the role model here, and that command (without paths) would
not remove the file. And applying it to a path should not change the
behavior, just restrict it to the paths, right?
--
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: [RFC] git checkout $tree -- $path always rewrites files

2014-11-08 Thread Martin von Zweigbergk
I'm not sure I had seen that particular thread, but it seems like
we're all in agreement on that topic. I'm keeping my fingers crossed
that Jeff will have time to tackle that this time :-)

On Fri, Nov 7, 2014 at 11:35 PM, Junio C Hamano  wrote:
> I think that has direct linkage; what you have in mind I think is
> http://thread.gmane.org/gmane.comp.version-control.git/234903/focus=234935
>
> What is on thread here is an implementation glitch, not semantic one.
> Checking out a "directory" as opposed to "set of paths that match the
> pathspec" was a deliberate design choice, not an implementation glitch.
>
> Pardon HTML, misspellings and grammos, typed on a tablet.
>
> On Nov 7, 2014 11:10 PM, "Martin von Zweigbergk" 
> wrote:
>>
>> Trying again from plain old gmail which I think does not send a
>> multipart content.
>>
>> On Fri, Nov 7, 2014 at 11:06 PM, Martin von Zweigbergk
>>  wrote:
>> > Is this also related to "git checkout $rev ." not removing removed
>> > files?
>> > What you say about the difference in implementation between checkout and
>> > reset sounds vaguely familiar from when I looked at it some years ago.
>> > Curiously, I just talked to Jonathan about this over lunch yesterday. I
>> > think we would both be happy to get that oddity of checkout fixed. If
>> > what
>> > you mention here is indeed related to fixing that, it does complicate
>> > things
>> > with regards to backwards compatibility.
>> >
>> >
>> > On Fri Nov 07 2014 at 11:24:09 AM Jeff King  wrote:
>> >>
>> >> On Fri, Nov 07, 2014 at 09:14:42AM -0800, Junio C Hamano wrote:
>> >>
>> >> > Jeff King  writes:
>> >> >
>> >> > > Is there a reason that we don't use this diff technique for
>> >> > > checkout?
>> >> >
>> >> > I suspect that the reasons are probably mixture of these:
>> >> >
>> >> >  (1) the code path may descend from checkout-index and predates the
>> >> >  in-core diff machinery;
>> >> >
>> >> >  (2) in the context of checkout-index, it was more desirable to be
>> >> >  able to say "I want the contents on the filesystem, even if you
>> >> >  think I already have it there, as you as a new software are
>> >> >  likely to be wrong and I know better"; or
>> >> >
>> >> >  (3) it was easier to code that way ;-)
>> >> >
>> >> > I do not see there is any reason not to do what you suggest.
>> >>
>> >> OK. It's not very much code (and can mostly be lifted from git-reset),
>> >> so I may take a stab at it.
>> >>
>> >> -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
--
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: [RFC] git checkout $tree -- $path always rewrites files

2014-11-07 Thread Martin von Zweigbergk
Trying again from plain old gmail which I think does not send a
multipart content.

On Fri, Nov 7, 2014 at 11:06 PM, Martin von Zweigbergk
 wrote:
> Is this also related to "git checkout $rev ." not removing removed files?
> What you say about the difference in implementation between checkout and
> reset sounds vaguely familiar from when I looked at it some years ago.
> Curiously, I just talked to Jonathan about this over lunch yesterday. I
> think we would both be happy to get that oddity of checkout fixed. If what
> you mention here is indeed related to fixing that, it does complicate things
> with regards to backwards compatibility.
>
>
> On Fri Nov 07 2014 at 11:24:09 AM Jeff King  wrote:
>>
>> On Fri, Nov 07, 2014 at 09:14:42AM -0800, Junio C Hamano wrote:
>>
>> > Jeff King  writes:
>> >
>> > > Is there a reason that we don't use this diff technique for checkout?
>> >
>> > I suspect that the reasons are probably mixture of these:
>> >
>> >  (1) the code path may descend from checkout-index and predates the
>> >  in-core diff machinery;
>> >
>> >  (2) in the context of checkout-index, it was more desirable to be
>> >  able to say "I want the contents on the filesystem, even if you
>> >  think I already have it there, as you as a new software are
>> >  likely to be wrong and I know better"; or
>> >
>> >  (3) it was easier to code that way ;-)
>> >
>> > I do not see there is any reason not to do what you suggest.
>>
>> OK. It's not very much code (and can mostly be lifted from git-reset),
>> so I may take a stab at it.
>>
>> -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
--
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: [RFC/PATCH] rebase: use reflog to find common base with upstream

2013-12-08 Thread Martin von Zweigbergk
On Sun, Dec 8, 2013 at 12:06 PM, John Keeping  wrote:
> Commit 15a147e (rebase: use @{upstream} if no upstream specified,
> 2011-02-09) says:
>
> Make it default to 'git rebase @{upstream}'. That is also what
> 'git pull [--rebase]' defaults to, so it only makes sense that
> 'git rebase' defaults to the same thing.
>
> but that isn't actually the case.  Since commit d44e712 (pull: support
> rebased upstream + fetch + pull --rebase, 2009-07-19), pull has actually
> chosen the most recent reflog entry which is an ancestor of the current
> branch if it can find one.

In my mind, 'git pull --rebase' does default to @{u}, it just started
interpreting it differently in d44e712, but maybe I'm just being
defensive :-).

In a similar way, I think your patch is about interpreting the
upstream argument differently, not about changing the default upstream
argument. This is why I think "git rebase" and "git rebase
origin/master" should be the same (when origin/master is the
configured upstream).
--
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 16/16] add: avoid yoda conditions

2013-10-31 Thread Martin von Zweigbergk
I was recently confused by the yoda condition in this block of code from [1]

+ for (i = 0; i < revs.nr; i++)
+ if (&bases->item->object == &revs.commit[i]->object)
+ break; /* found */
+ if (revs.nr <= i)

I think I was particularly surprised because it came so soon after the
"i < revs.nr". I didn't bother commenting because it seemed too
subjective and the code base has tons of these. Something as simple as

  git grep '[0-9] [<>]' *.c

finds a bunch (probably with lots of false positives and negatives).

I guess what I'm trying to say is that either we accept them and get
used to reading them without being surprised, or we can change a bit
more than one at a time perhaps? I understand that this was an
occurrence you just happened to run into, and I'm not saying that a
patch has to deal with _all_ occurrences. I'm more just wondering if
we want mention our position, whatever it is, in CodingGuidelines.

Martin

[1] http://thread.gmane.org/gmane.comp.version-control.git/236252/focus=236716

On Thu, Oct 31, 2013 at 2:25 AM, Felipe Contreras
 wrote:
> Signed-off-by: Felipe Contreras 
> ---
>  builtin/add.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/builtin/add.c b/builtin/add.c
> index 226f758..9b30356 100644
> --- a/builtin/add.c
> +++ b/builtin/add.c
> @@ -429,7 +429,7 @@ int cmd_add(int argc, const char **argv, const char 
> *prefix)
> argc--;
> argv++;
>
> -   if (0 <= addremove_explicit)
> +   if (addremove_explicit >= 0)
> addremove = addremove_explicit;
> else if (take_worktree_changes && ADDREMOVE_DEFAULT)
> addremove = 0; /* "-u" was given but not "-A" */
> --
> 1.8.4.2+fc1
>
> --
> To unsubscribe from this list: send the line "unsubscribe git" in
> the body of a message to majord...@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
--
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 2/2] merge-base: teach "--fork-point" mode

2013-10-25 Thread Martin von Zweigbergk
Thanks for taking care of this! Maybe John or I can finally get the
changes to rebase done after this.

A few comments below. Sorry I didn't find time to review the earlier revisions.

On Fri, Oct 25, 2013 at 2:38 PM, Junio C Hamano  wrote:
> +
> +where `origin/master` used to point at commits B3, B2, B1 and now it
> +points at B, and your `topic` branch was stated on top of it back

s/stated/started/

> +   bases = get_merge_bases_many(derived, revs.nr, revs.commit, 0);
> +
> +   /*
> +* There should be one and only one merge base, when we found
> +* a common ancestor among reflog entries.
> +*/
> +   if (!bases || bases->next)
> +   return 1;
> +
> +   /* And the found one must be one of the reflog entries */
> +   for (i = 0; i < revs.nr; i++)
> +   if (&bases->item->object == &revs.commit[i]->object)
> +   break; /* found */
> +   if (revs.nr <= i)
> +   return 1; /* not found */
> +
> +   printf("%s\n", sha1_to_hex(bases->item->object.sha1));
> +   free_commit_list(bases);
> +   return 0;

Should free_commit_list also be called in the two "return 1" cases
above? I suppose the process will exit soon after this, but that seems
to be true for all three cases.

> diff --git a/t/t6010-merge-base.sh b/t/t6010-merge-base.sh
> index f80bba8..4f09db0 100755
> --- a/t/t6010-merge-base.sh
> +++ b/t/t6010-merge-base.sh
> @@ -230,4 +230,31 @@ test_expect_success 'criss-cross merge-base for 
> octopus-step' '
> test_cmp expected.sorted actual.sorted
>  '
>
> +test_expect_success 'using reflog to find the fork point' '
> +   git reset --hard &&
> +   git checkout -b base $E &&
> +
> +   (
> +   for count in 1 2 3 4 5
> +   do
> +   git commit --allow-empty -m "Base commit #$count" &&
> +   git rev-parse HEAD >expect$count &&
> +   git checkout -B derived &&
> +   git commit --allow-empty -m "Derived #$count" &&
> +   git rev-parse HEAD >derived$count &&
> +   git checkout base || exit 1

I think this creates a history like

---E---B1--B2--B3--B4--B5 (base)
\   \   \   \   \
 D1  D2  D3  D4  D5 (derived)

So I think the following test would pass even if you drop the
--fork-point. Did you mean to create a fan-shaped history by resetting
base to $E on every iteration above?

> +   git merge-base --fork-point base $(cat derived$count) 
> >actual &&
> +   test_cmp expect$count actual || exit 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


Re: Re* Bug report: reset -p HEAD

2013-10-24 Thread Martin von Zweigbergk
Sorry about the regression and thanks for report and fixes.

On Thu, Oct 24, 2013 at 9:24 PM, Jeff King  wrote:
> On Thu, Oct 24, 2013 at 08:40:13PM -0700, Junio C Hamano wrote:
>
>> Maarten de Vries  writes:
>>
>> > Some more info: It used to work as intended. Using a bisect shows it
>> > has been broken by commit 166ec2e9.
>>
>> Thanks.
>>
>> A knee-jerk change without thinking what side-effect it has for you
>> to try out.
>>
>>  builtin/reset.c | 5 -
>>  1 file changed, 4 insertions(+), 1 deletion(-)
>>
>> diff --git a/builtin/reset.c b/builtin/reset.c
>> index f2f9d55..a3088d9 100644
>> --- a/builtin/reset.c
>> +++ b/builtin/reset.c
>> @@ -304,7 +304,10 @@ int cmd_reset(int argc, const char **argv, const char 
>> *prefix)
>>   if (patch_mode) {
>>   if (reset_type != NONE)
>>   die(_("--patch is incompatible with 
>> --{hard,mixed,soft}"));
>> - return run_add_interactive(sha1_to_hex(sha1), "--patch=reset", 
>> &pathspec);
>> + return run_add_interactive(
>> + (unborn || strcmp(rev, "HEAD"))
>> + ? sha1_to_hex(sha1)
>> + : "HEAD", "--patch=reset", &pathspec);
>>   }
>
> I think that's the correct fix for the regression.  You are restoring
> the original, pre-166ec2e9 behavior for just the HEAD case. I do not
> think add--interactive does any other magic between a symbolic rev and
> its sha1, except for recognizing HEAD specially. However, if you wanted
> to minimize the potential impact of 166ec2e9, you could pass the sha1
> _only_ in the unborn case, like this:

Plus, the end result is more readable, IMHO.

> diff --git a/builtin/reset.c b/builtin/reset.c
> index f2f9d55..bfdd8d3 100644
> --- a/builtin/reset.c
> +++ b/builtin/reset.c
> @@ -283,6 +283,7 @@ int cmd_reset(int argc, const char **argv, const char 
> *prefix)
> if (unborn) {
> /* reset on unborn branch: treat as reset to empty tree */
> hashcpy(sha1, EMPTY_TREE_SHA1_BIN);
> +   rev = EMPTY_TREE_SHA1_HEX;
> } else if (!pathspec.nr) {
> struct commit *commit;
> if (get_sha1_committish(rev, sha1))
> @@ -304,7 +305,7 @@ int cmd_reset(int argc, const char **argv, const char 
> *prefix)
> if (patch_mode) {
> if (reset_type != NONE)
> die(_("--patch is incompatible with 
> --{hard,mixed,soft}"));
> -   return run_add_interactive(sha1_to_hex(sha1), 
> "--patch=reset", &pathspec);
> +   return run_add_interactive(rev, "--patch=reset", &pathspec);
> }
>
> /* git reset tree [--] paths... can be used to
>
> That fixes any possible regression from add--interactive treating the
> two cases differently. On an unborn branch, we will still say "apply
> this hunk" rather than "unstage this hunk". That's not a regression,
> because it simply didn't work before, but it's not ideal. To fix that,
> we need to somehow tell add--interactive "this is HEAD, but use the
> empty tree because it's unborn". I can think of a few simple-ish ways:
>
>   1. Pass the head/not-head flag as a separate option.
>
>   2. Pass HEAD even in the unborn case; teach add--interactive to
>  convert an unborn HEAD to the empty tree.
>
>   3. Teach add--interactive to recognize the empty tree sha1 as an
>  "unstage" path.
>
> I kind of like (3). At first glance, it is wrong; we will also treat
> "git reset -p $(git hash-object -t tree /dev/null)" as if "HEAD" had
> been passed. But if you are explicitly passing the empty tree like that,
> I think saying "unstage" makes a lot of sense.

Makes sense to me. I'm sure others can implement that much faster than
I can, but I feel a little guilty, so I'm happy to do it if no one
else wants to, as long as we agree this is the way we want to go.
--
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] rebase: use reflog to find common base with upstream

2013-10-21 Thread Martin von Zweigbergk
On Mon, Oct 21, 2013 at 4:24 AM, John Keeping  wrote:
> On Sun, Oct 20, 2013 at 10:03:29PM -0700, Martin von Zweigbergk wrote:
>> On Wed, Oct 16, 2013 at 11:53 AM, John Keeping  wrote:
>> > Commit 15a147e (rebase: use @{upstream} if no upstream specified,
>> > 2011-02-09) says:
>> >
>> > Make it default to 'git rebase @{upstream}'. That is also what
>> > 'git pull [--rebase]' defaults to, so it only makes sense that
>> > 'git rebase' defaults to the same thing.
>> >
>> > but that isn't actually the case.  Since commit d44e712 (pull: support
>> > rebased upstream + fetch + pull --rebase, 2009-07-19), pull has actually
>> > chosen the most recent reflog entry which is an ancestor of the current
>> > branch if it can find one.
>>
>> It is exactly this inconsistency between "git rebase" and "git pull
>> --rebase" that confused me enough to make me send my first email to
>> this list almost 4 years ago [1], so thanks for working on this! I
>> finished that thread with:
>>
>>   Would it make sense to teach "git rebase" the same tricks as "git
>> pull --rebase"?
>>
>> Then it took me a year before I sent a patch not unlike this one [2].
>> To summarize, the patch did not get accepted then because it makes
>> rebase a little slower (or a lot slower in some cases). "git pull
>> --rebase" is of course at least as slow in the same cases, but because
>> it often involves connecting to a remote host, people would probably
>> blame the connection rather than git itself even in those rare (?)
>> cases.
>>
>> I think
>>
>>   git merge-base HEAD $(git rev-list -g "$upstream_name")
>>
>> is roughly correct and hopefully fast enough. That can lead to too
>> long a command line, so I was planning on teaching merge-base a
>> --stdin option, but never got around to it.
>
> I'm not sure we should worry about the additional overhead here.  In the
> common case, we should hit a common ancestor within the first couple of
> reflog entries; and in the case that will be slow, it's likely that
> there are a lot of differences between the branches so the cherry
> comparison phase will take a while anyway.

Perhaps true. I created a simple commit based on my origin/master@{1}
in git.git, which happened to be 136 commits behind origin/master.
Before (a modified version of) your patch, it took 0.756s to rebase it
(best of 5) and afterwards it took 0.720s.

And in a worse case: The same test with one commit off my
origin/master@{13}, 2910 behind origin/master, shows an increase from
2.75s to 4.04s.

And a degenerate case: I created a test branch (called u) with
1000-entry reflog from the output of "git rev-list --first-parent
origin/master | head -1000 | tac" and created the same simple commit
as before off of the end of this reflog (u@{999}). This ended up 3769
commits behind u@{0} (aka origin/master). In this case it went from
3.43s to 3m32s. Obviously, this was a degenerate case designed to be
slow, but I think it's still worth noting that one can get such O(n^2)
behavior e.g. if one lets a branch get out of sync with an upstream
that's very frequently fetches (I've heard of people running
short-interval cron jobs that fetch from a remote).

I do like the feature, but I'm still concerned about this last 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] rebase: use reflog to find common base with upstream

2013-10-21 Thread Martin von Zweigbergk
On Wed, Oct 16, 2013 at 11:53 AM, John Keeping  wrote:
> Commit 15a147e (rebase: use @{upstream} if no upstream specified,
> 2011-02-09) says:
>
> Make it default to 'git rebase @{upstream}'. That is also what
> 'git pull [--rebase]' defaults to, so it only makes sense that
> 'git rebase' defaults to the same thing.
>
> but that isn't actually the case.  Since commit d44e712 (pull: support
> rebased upstream + fetch + pull --rebase, 2009-07-19), pull has actually
> chosen the most recent reflog entry which is an ancestor of the current
> branch if it can find one.
>
> Change rebase so that it uses the same logic.
>
> Signed-off-by: John Keeping 
> ---
>  git-rebase.sh | 8 
>  t/t3400-rebase.sh | 6 --
>  2 files changed, 12 insertions(+), 2 deletions(-)
>
> diff --git a/git-rebase.sh b/git-rebase.sh
> index 226752f..fd36cf7 100755
> --- a/git-rebase.sh
> +++ b/git-rebase.sh
> @@ -437,6 +437,14 @@ then
> error_on_missing_default_upstream "rebase" "rebase" \
> "against" "git rebase "
> fi
> +   for reflog in $(git rev-list -g "$upstream_name" 2>/dev/null)
> +   do
> +   if test "$reflog" = "$(git merge-base "$reflog" HEAD)"
> +   then
> +   upstream_name=$reflog
> +   break
> +   fi
> +   done
> ;;
> *)  upstream_name="$1"
> shift

A little later, "onto_name" gets assigned like so:

  onto_name=${onto-"$upstream_name"}

So if upstream_name was set above, then onto would get the same value,
which is not what we want, right? It seems like this block of code
should come a bit later.

I also think it not be run only when rebase was run without a given
upstream. If the configured upstream is "origin/master", it seems like
it would be surprising to get different behavior from "git rebase" and
"git rebase origin/master".
--
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] rebase: use reflog to find common base with upstream

2013-10-20 Thread Martin von Zweigbergk
On Wed, Oct 16, 2013 at 11:53 AM, John Keeping  wrote:
> Commit 15a147e (rebase: use @{upstream} if no upstream specified,
> 2011-02-09) says:
>
> Make it default to 'git rebase @{upstream}'. That is also what
> 'git pull [--rebase]' defaults to, so it only makes sense that
> 'git rebase' defaults to the same thing.
>
> but that isn't actually the case.  Since commit d44e712 (pull: support
> rebased upstream + fetch + pull --rebase, 2009-07-19), pull has actually
> chosen the most recent reflog entry which is an ancestor of the current
> branch if it can find one.

It is exactly this inconsistency between "git rebase" and "git pull
--rebase" that confused me enough to make me send my first email to
this list almost 4 years ago [1], so thanks for working on this! I
finished that thread with:

  Would it make sense to teach "git rebase" the same tricks as "git
pull --rebase"?

Then it took me a year before I sent a patch not unlike this one [2].
To summarize, the patch did not get accepted then because it makes
rebase a little slower (or a lot slower in some cases). "git pull
--rebase" is of course at least as slow in the same cases, but because
it often involves connecting to a remote host, people would probably
blame the connection rather than git itself even in those rare (?)
cases.

I think

  git merge-base HEAD $(git rev-list -g "$upstream_name")

is roughly correct and hopefully fast enough. That can lead to too
long a command line, so I was planning on teaching merge-base a
--stdin option, but never got around to it.

Martin


[1] http://thread.gmane.org/gmane.comp.version-control.git/136339
[2] http://thread.gmane.org/gmane.comp.version-control.git/166710
--
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 04/13] Use "git merge" instead of "git pull ."

2013-08-24 Thread Martin von Zweigbergk
On Sat, Aug 24, 2013 at 9:19 PM, Jonathan Nieder  wrote:
> Thomas Ackermann wrote:
>> --- a/Documentation/user-manual.txt
>> +++ b/Documentation/user-manual.txt
>> @@ -1784,17 +1784,6 @@ repository that you pulled from.
>>  <>; instead, your branch will just be
>>  updated to point to the latest commit from the upstream branch.)
>>
>> -The `git pull` command can also be given `.` as the "remote" repository,
>> -in which case it just merges in a branch from the current repository; so
>> -the commands
>> -
>> --
>> -$ git pull . branch
>> -$ git merge branch
>> --
>> -
>> -are roughly equivalent.  The former is actually very commonly used.
>> -
>
> I wonder if it would make sense to say they simply *are* equivalent.
> I.e., what differences are there between those two commands, and could
> "git pull" be tweaked to eliminate them?

One difference is that "git pull" can be configured to rebase.

> [...]
>> @@ -2259,7 +2248,7 @@ When you are happy with the state of this change, you 
>> can pull it into the
>>  "test" branch in preparation to make it public:

I realize that "pull" here is not necessarily about the command, but
perhaps it would still make sense to change it?
--
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: detached HEAD before root commit - possible?

2013-06-23 Thread Martin von Zweigbergk
On Sun, Jun 23, 2013 at 4:54 PM, Jonathan Nieder  wrote:
>
> In other words, HEAD always either points to an unborn or existing
> branch or an existing commit.  It's not clear to me what it would
> mean to detach from an unborn branch.

I think it should mean that the next commit would be a root commit (of
course) and that HEAD would be detached and point to that commit. I
find that it helps to think of unborn branches (and "unborn" detached
HEAD) as pointing to some fixed root commit.

I wanted an "unborn detached HEAD" once when working on rebase.
Imagine what "git rebase --root" would do when run on a detached HEAD.
It is currently slightly broken because it forces the rebase (i.e.
creates a new root commit). This is inconsistent with e.g. "git rebase
HEAD~10", which won't do anything (assuming linear history). It would
have been nice if "git rebase --root" could be implemented as:

 1. create unborn detached HEAD
 2. cherry-pick commits
 3. set branch (or not, if started from detached HEAD)

Instead, what I ended up doing at some point was to create a temporary
unborn branch that I deleted after picking the first commit.

Anyway, that was just to show another point of view; I'm not
suggesting we should implement support for unborn detached HEAD.

Martin
--
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 mz/rebase-tests] rebase topology tests: fix commit names on case-insensitive file systems

2013-06-18 Thread Martin von Zweigbergk
On Tue, Jun 18, 2013 at 12:28 AM, Johannes Sixt  wrote:
>
> The recently introduced tests used uppercase letters to denote
> cherry-picks of commits having the corresponding lowercase letter names.
> The helper functions also set up tags with the names of the commits.
>
> But this constellation fails on case-insensitive file systems because
> there cannot be distinct tags with names that differ only in case.
>
> Use a less subtle convention for the names of cherry-picked commits.

Makes sense, and the patch looks good. Thanks.

>  Knowing that the tests would take their time to complete on Windows,

I'm curious just how slow it is. Are we talking minutes?
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 1/3] rebase: guard against missing files in read_basic_state()

2013-06-15 Thread Martin von Zweigbergk
On Thu, Jun 13, 2013 at 3:29 PM, Junio C Hamano  wrote:
> Ramkumar Ramachandra  writes:
>
> A more troublesome is that nobody seems to check the return value of
> this function.  If head-name, onto or orig-head is missing, is that
> an error condition that should make the callers of read_basic_state
> stop and refuse to proceed?

Since we unconditionally write those three (and 'quiet'), it seems
reasonable to require all of them to be there when continuing, so I
think you're right that we should fail fast.

> The way the && cascade is used seems to indicate that, but up to the
> point where it sents $verbose. If and only if head-name, onto, orig-head
> and quiet can be read in state-dir, verbose in state-dir is checked
> and only then $verbose is set.
>
> Martin, this seems to be from your series around early Feburary
> 2011.  Do you recall why these checks are cascaded this way?
> I do not offhand think of a good reason.

Neither do I. I think the cascading after 'quiet' is just a mistake on
my part. The consequences are probably close to none, since if one of
earlier commands fail, the other files will probably not be there
either. (Not defending it; I'm happy if it gets fixed, e.g. by making
it fail fast.)
--
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] reset: trivial refactoring

2013-06-13 Thread Martin von Zweigbergk
On Thu, Jun 13, 2013 at 11:15 AM, Felipe Contreras
 wrote:
> @@ -82,7 +82,7 @@ static int reset_index(const unsigned char *sha1, int 
> reset_type, int quiet)
> if (unpack_trees(nr, desc, &opts))
> return -1;
>
> -   if (reset_type == MIXED || reset_type == HARD) {
> +   if (reset_type == HARD) {

Are you sure that this can not be reached given that...

> @@ -323,8 +323,11 @@ int cmd_reset(int argc, const char **argv, const char 
> *prefix)
> struct lock_file *lock = xcalloc(1, sizeof(struct lock_file));
> int newfd = hold_locked_index(lock, 1);
> if (reset_type == MIXED) {
> +   int flags = quiet ? REFRESH_QUIET : 
> REFRESH_IN_PORCELAIN;
> if (read_from_tree(pathspec, sha1))
> return 1;
> +   refresh_index(&the_index, flags, NULL, NULL,
> + _("Unstaged changes after reset:"));
> } else {
> int err = reset_index(sha1, reset_type, quiet);
> if (reset_type == KEEP && !err)

...the line after this one reads

   err = reset_index(sha1, MIXED, quiet);

? I don't know what the consequence of not calling prime_cache_tree()
would be, though.

The merging of the two if blocks looks good. 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: [PATCH v4 45/45] tests: update topology tests

2013-06-10 Thread Martin von Zweigbergk
On Sun, Jun 9, 2013 at 9:40 AM, Felipe Contreras
 wrote:
> Signed-off-by: Felipe Contreras 
> ---
>  t/t3425-rebase-topology-merges.sh | 15 ++-
>  1 file changed, 6 insertions(+), 9 deletions(-)
>
> diff --git a/t/t3425-rebase-topology-merges.sh 
> b/t/t3425-rebase-topology-merges.sh
> index 5400a05..96cc479 100755
> --- a/t/t3425-rebase-topology-merges.sh
> +++ b/t/t3425-rebase-topology-merges.sh
> @@ -70,9 +70,8 @@ test_run_rebase () {
> test_linear_range "\'"$expected"\'" d..
> "
>  }
> -#TODO: make order consistent across all flavors of rebase
> -test_run_rebase success 'e n o' ''
> -test_run_rebase success 'e n o' -m
> +test_run_rebase success 'n o e' ''
> +test_run_rebase success 'n o e' -m
>  test_run_rebase success 'n o e' -i

If you do end up re-sending the series on top of my series, I'd prefer
to see the end result having the first argument inlined, so these few
lines become simply:

test_run_rebase success ''
test_run_rebase success -m
test_run_rebase success -i
--
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: Bad attitudes and problems in the Git community (was: Re: [PATCH 2/2] Move sequencer to builtin)

2013-06-10 Thread Martin von Zweigbergk
Yes, sorry. I find this whole story quite amusing (albeit distracting
and unnecessary), but sorry for adding to the spam. I'll be quiet now.

On Mon, Jun 10, 2013 at 11:33 AM, Martin Langhoff
 wrote:
> On Mon, Jun 10, 2013 at 2:11 PM, Martin von Zweigbergk
>  wrote:
>> On Mon, Jun 10, 2013 at 9:58 AM, Felipe Contreras
>>  wrote:
>>> On Mon, Jun 10, 2013 at 4:05 AM, Stefano Lattarini
>>>  wrote:
>>>
>>>>> You need two sides to have an argument.
>>>
>>>> I disagree.  Unless you mean than, whenever a part behaves in a
>>>> hostile and aggressive way, the other part should just silently
>>>> knuckle under.
>>>
>>> You are wrong. If a bum in the street starts talking about you about
>>> why you are going to hell, and you reply to him and argue. Who has the
>>> fault of starting an argument?
>>
>> I'm not sure I follow the analogy. Are you the bum or the passer-by?
>
> http://xkcd.com/386/
>
> Someone is wrong on the Internet!
>
> Let it be.
>
>
> m
> --
>  martin.langh...@gmail.com
>  -  ask interesting questions
>  - don't get distracted with shiny stuff  - working code first
>  ~ http://docs.moodle.org/en/User:Martin_Langhoff
--
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: Bad attitudes and problems in the Git community (was: Re: [PATCH 2/2] Move sequencer to builtin)

2013-06-10 Thread Martin von Zweigbergk
On Mon, Jun 10, 2013 at 9:58 AM, Felipe Contreras
 wrote:
> On Mon, Jun 10, 2013 at 4:05 AM, Stefano Lattarini
>  wrote:
>
>>> You need two sides to have an argument.
>
>> I disagree.  Unless you mean than, whenever a part behaves in a
>> hostile and aggressive way, the other part should just silently
>> knuckle under.
>
> You are wrong. If a bum in the street starts talking about you about
> why you are going to hell, and you reply to him and argue. Who has the
> fault of starting an argument?

I'm not sure I follow the analogy. Are you the bum or the passer-by?

Sorry, couldn't help it. :-)
--
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 v6 5/7] add tests for rebasing merged history

2013-06-06 Thread Martin von Zweigbergk
Signed-off-by: Martin von Zweigbergk 
---
 t/t3400-rebase.sh |  31 +
 t/t3401-rebase-partial.sh |  45 ---
 t/t3404-rebase-interactive.sh |  10 +-
 t/t3409-rebase-preserve-merges.sh |  53 
 t/t3425-rebase-topology-merges.sh | 258 ++
 5 files changed, 260 insertions(+), 137 deletions(-)
 delete mode 100755 t/t3401-rebase-partial.sh
 create mode 100755 t/t3425-rebase-topology-merges.sh

diff --git a/t/t3400-rebase.sh b/t/t3400-rebase.sh
index b58fa1a..b436ef4 100755
--- a/t/t3400-rebase.sh
+++ b/t/t3400-rebase.sh
@@ -40,13 +40,6 @@ test_expect_success 'prepare repository with topic branches' 
'
echo Side >>C &&
git add C &&
git commit -m "Add C" &&
-   git checkout -b nonlinear my-topic-branch &&
-   echo Edit >>B &&
-   git add B &&
-   git commit -m "Modify B" &&
-   git merge side &&
-   git checkout -b upstream-merged-nonlinear &&
-   git merge master &&
git checkout -f my-topic-branch &&
git tag topic
 '
@@ -106,31 +99,9 @@ test_expect_success 'rebase from ambiguous branch name' '
git rebase master
 '
 
-test_expect_success 'rebase after merge master' '
-   git checkout --detach refs/tags/topic &&
-   git branch -D topic &&
-   git reset --hard topic &&
-   git merge master &&
-   git rebase master &&
-   ! (git show | grep "^Merge:")
-'
-
-test_expect_success 'rebase of history with merges is linearized' '
-   git checkout nonlinear &&
-   test 4 = $(git rev-list master.. | wc -l) &&
-   git rebase master &&
-   test 3 = $(git rev-list master.. | wc -l)
-'
-
-test_expect_success 'rebase of history with merges after upstream merge is 
linearized' '
-   git checkout upstream-merged-nonlinear &&
-   test 5 = $(git rev-list master.. | wc -l) &&
-   git rebase master &&
-   test 3 = $(git rev-list master.. | wc -l)
-'
-
 test_expect_success 'rebase a single mode change' '
git checkout master &&
+   git branch -D topic &&
echo 1 >X &&
git add X &&
test_tick &&
diff --git a/t/t3401-rebase-partial.sh b/t/t3401-rebase-partial.sh
deleted file mode 100755
index 7ba1797..000
--- a/t/t3401-rebase-partial.sh
+++ /dev/null
@@ -1,45 +0,0 @@
-#!/bin/sh
-#
-# Copyright (c) 2006 Yann Dirson, based on t3400 by Amos Waterland
-#
-
-test_description='git rebase should detect patches integrated upstream
-
-This test cherry-picks one local change of two into master branch, and
-checks that git rebase succeeds with only the second patch in the
-local branch.
-'
-. ./test-lib.sh
-
-test_expect_success 'prepare repository with topic branch' '
-   test_commit A &&
-   git checkout -b my-topic-branch &&
-   test_commit B &&
-   test_commit C &&
-   git checkout -f master &&
-   test_commit A2 A.t
-'
-
-test_expect_success 'pick top patch from topic branch into master' '
-   git cherry-pick C &&
-   git checkout -f my-topic-branch
-'
-
-test_debug '
-   git cherry master &&
-   git format-patch -k --stdout --full-index master >/dev/null &&
-   gitk --all & sleep 1
-'
-
-test_expect_success 'rebase topic branch against new master and check git am 
did not get halted' '
-   git rebase master &&
-   test_path_is_missing .git/rebase-apply
-'
-
-test_expect_success 'rebase --merge topic branch that was partially merged 
upstream' '
-   git reset --hard C &&
-   git rebase --merge master &&
-   test_path_is_missing .git/rebase-merge
-'
-
-test_done
diff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh
index a58406d..ffcaf02 100755
--- a/t/t3404-rebase-interactive.sh
+++ b/t/t3404-rebase-interactive.sh
@@ -477,19 +477,11 @@ test_expect_success 'interrupted squash works as expected 
(case 2)' '
test $one = $(git rev-parse HEAD~2)
 '
 
-test_expect_success 'ignore patch if in upstream' '
-   HEAD=$(git rev-parse HEAD) &&
-   git checkout -b has-cherry-picked HEAD^ &&
+test_expect_success '--continue tries to commit, even for "edit"' '
echo unrelated > file7 &&
git add file7 &&
test_tick &&
git commit -m "unrelated change" &&
-   git cherry-pick $HEAD &&
-   EXPECT_C

[PATCH v6 0/8] Rebase topology test

2013-06-06 Thread Martin von Zweigbergk
Changes since v5:

 * Improved test_linear_range
 * Changed TODOs to be about consistency, not --topo-order

Martin von Zweigbergk (7):
  add simple tests of consistency across rebase types
  add tests for rebasing with patch-equivalence present
  add tests for rebasing of empty commits
  add tests for rebasing root
  add tests for rebasing merged history
  t3406: modernize style
  tests: move test for rebase messages from t3400 to t3406

 t/lib-rebase.sh   |  33 
 t/t3400-rebase.sh |  53 +-
 t/t3401-rebase-partial.sh |  69 
 t/t3404-rebase-interactive.sh |  10 +-
 t/t3406-rebase-message.sh |  50 +++---
 t/t3409-rebase-preserve-merges.sh |  53 --
 t/t3421-rebase-topology-linear.sh | 350 ++
 t/t3425-rebase-topology-merges.sh | 258 
 8 files changed, 673 insertions(+), 203 deletions(-)
 delete mode 100755 t/t3401-rebase-partial.sh
 create mode 100755 t/t3421-rebase-topology-linear.sh
 create mode 100755 t/t3425-rebase-topology-merges.sh

-- 
1.8.3.497.g83fddbe

--
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 v6 6/7] t3406: modernize style

2013-06-06 Thread Martin von Zweigbergk
Update the following:

 - Quote 'setup'
 - Remove blank lines within test case body
 - Use test_commit instead of custom quick_one
 - Create branch "topic" from tag created by test_commit

Signed-off-by: Martin von Zweigbergk 
---
 t/t3406-rebase-message.sh | 30 +-
 1 file changed, 9 insertions(+), 21 deletions(-)

diff --git a/t/t3406-rebase-message.sh b/t/t3406-rebase-message.sh
index e6a9a0d..fe8c27f 100755
--- a/t/t3406-rebase-message.sh
+++ b/t/t3406-rebase-message.sh
@@ -4,27 +4,17 @@ test_description='messages from rebase operation'
 
 . ./test-lib.sh
 
-quick_one () {
-   echo "$1" >"file$1" &&
-   git add "file$1" &&
-   test_tick &&
-   git commit -m "$1"
-}
+test_expect_success 'setup' '
+   test_commit O fileO &&
+   test_commit X fileX &&
+   test_commit A fileA &&
+   test_commit B fileB &&
+   test_commit Y fileY &&
 
-test_expect_success setup '
-   quick_one O &&
-   git branch topic &&
-   quick_one X &&
-   quick_one A &&
-   quick_one B &&
-   quick_one Y &&
-
-   git checkout topic &&
-   quick_one A &&
-   quick_one B &&
-   quick_one Z &&
+   git checkout -b topic O &&
+   git cherry-pick A B &&
+   test_commit Z fileZ &&
git tag start
-
 '
 
 cat >expect <<\EOF
@@ -34,12 +24,10 @@ Committed: 0003 Z
 EOF
 
 test_expect_success 'rebase -m' '
-
git rebase -m master >report &&
sed -n -e "/^Already applied: /p" \
-e "/^Committed: /p" report >actual &&
test_cmp expect actual
-
 '
 
 test_expect_success 'rebase --stat' '
-- 
1.8.3.497.g83fddbe

--
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 v6 2/7] add tests for rebasing with patch-equivalence present

2013-06-06 Thread Martin von Zweigbergk
Signed-off-by: Martin von Zweigbergk 
---
 t/lib-rebase.sh   | 17 
 t/t3421-rebase-topology-linear.sh | 85 +++
 2 files changed, 102 insertions(+)

diff --git a/t/lib-rebase.sh b/t/lib-rebase.sh
index 1e0ff28..4b74ae4 100644
--- a/t/lib-rebase.sh
+++ b/t/lib-rebase.sh
@@ -81,3 +81,20 @@ reset_rebase () {
git reset --hard &&
git clean -f
 }
+
+cherry_pick () {
+   git cherry-pick -n "$2" &&
+   git commit -m "$1" &&
+   git tag "$1"
+}
+
+revert () {
+   git revert -n "$2" &&
+   git commit -m "$1" &&
+   git tag "$1"
+}
+
+make_empty () {
+   git commit --allow-empty -m "$1" &&
+   git tag "$1"
+}
diff --git a/t/t3421-rebase-topology-linear.sh 
b/t/t3421-rebase-topology-linear.sh
index 60365d1..ddcbfc6 100755
--- a/t/t3421-rebase-topology-linear.sh
+++ b/t/t3421-rebase-topology-linear.sh
@@ -75,4 +75,89 @@ test_run_rebase success -m
 test_run_rebase success -i
 test_run_rebase success -p
 
+#   f
+#  /
+# a---b---c---g---h
+#  \
+#   d---G---i
+#
+# uppercase = cherry-picked
+# h = reverted g
+#
+# Reverted patches are there for tests to be able to check if a commit
+# that introduced the same change as another commit is
+# dropped. Without reverted commits, we could get false positives
+# because applying the patch succeeds, but simply results in no
+# changes.
+test_expect_success 'setup of linear history for range selection tests' '
+   git checkout c &&
+   test_commit g &&
+   revert h g &&
+   git checkout d &&
+   cherry_pick G g &&
+   test_commit i &&
+   git checkout b &&
+   test_commit f
+'
+
+test_run_rebase () {
+   result=$1
+   shift
+   test_expect_$result "rebase $* drops patches in upstream" "
+   reset_rebase &&
+   git rebase $* h i &&
+   test_cmp_rev h HEAD~2 &&
+   test_linear_range 'd i' h..
+   "
+}
+test_run_rebase success ''
+test_run_rebase failure -m
+test_run_rebase success -i
+test_run_rebase success -p
+
+test_run_rebase () {
+   result=$1
+   shift
+   test_expect_$result "rebase $* can drop last patch if in upstream" "
+   reset_rebase &&
+   git rebase $* h G &&
+   test_cmp_rev h HEAD^ &&
+   test_linear_range 'd' h..
+   "
+}
+test_run_rebase success ''
+test_run_rebase failure -m
+test_run_rebase success -i
+test_run_rebase success -p
+
+test_run_rebase () {
+   result=$1
+   shift
+   test_expect_$result "rebase $* --onto drops patches in upstream" "
+   reset_rebase &&
+   git rebase $* --onto f h i &&
+   test_cmp_rev f HEAD~2 &&
+   test_linear_range 'd i' f..
+   "
+}
+test_run_rebase success ''
+test_run_rebase failure -m
+test_run_rebase success -i
+test_run_rebase success -p
+
+test_run_rebase () {
+   result=$1
+   shift
+   test_expect_$result "rebase $* --onto does not drop patches in onto" "
+   reset_rebase &&
+   git rebase $* --onto h f i &&
+   test_cmp_rev h HEAD~3 &&
+   test_linear_range 'd G i' h..
+   "
+}
+test_run_rebase success ''
+test_run_rebase success -m
+test_run_rebase success -i
+test_run_rebase success -p
+
 test_done
-- 
1.8.3.497.g83fddbe

--
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 v6 1/7] add simple tests of consistency across rebase types

2013-06-06 Thread Martin von Zweigbergk
Helped-by: Johannes Sixt 
Signed-off-by: Martin von Zweigbergk 
---
 t/lib-rebase.sh   | 16 
 t/t3421-rebase-topology-linear.sh | 78 +++
 2 files changed, 94 insertions(+)
 create mode 100755 t/t3421-rebase-topology-linear.sh

diff --git a/t/lib-rebase.sh b/t/lib-rebase.sh
index 6ccf797..1e0ff28 100644
--- a/t/lib-rebase.sh
+++ b/t/lib-rebase.sh
@@ -65,3 +65,19 @@ EOF
test_set_editor "$(pwd)/fake-editor.sh"
chmod a+x fake-editor.sh
 }
+
+# checks that the revisions in "$2" represent a linear range with the
+# subjects in "$1"
+test_linear_range () {
+   revlist_merges=$(git rev-list --merges "$2") &&
+   test -z "$revlist_merges" &&
+   expected=$1
+   set -- $(git log --reverse --format=%s "$2")
+   test "$expected" = "$*"
+}
+
+reset_rebase () {
+   test_might_fail git rebase --abort &&
+   git reset --hard &&
+   git clean -f
+}
diff --git a/t/t3421-rebase-topology-linear.sh 
b/t/t3421-rebase-topology-linear.sh
new file mode 100755
index 000..60365d1
--- /dev/null
+++ b/t/t3421-rebase-topology-linear.sh
@@ -0,0 +1,78 @@
+#!/bin/sh
+
+test_description='basic rebase topology tests'
+. ./test-lib.sh
+. "$TEST_DIRECTORY"/lib-rebase.sh
+
+# a---b---c
+#  \
+#   d---e
+test_expect_success 'setup' '
+   test_commit a &&
+   test_commit b &&
+   test_commit c &&
+   git checkout b &&
+   test_commit d &&
+   test_commit e
+'
+
+test_run_rebase () {
+   result=$1
+   shift
+   test_expect_$result "simple rebase $*" "
+   reset_rebase &&
+   git rebase $* c e &&
+   test_cmp_rev c HEAD~2 &&
+   test_linear_range 'd e' c..
+   "
+}
+test_run_rebase success ''
+test_run_rebase success -m
+test_run_rebase success -i
+test_run_rebase success -p
+
+test_run_rebase () {
+   result=$1
+   shift
+   test_expect_$result "rebase $* is no-op if upstream is an ancestor" "
+   reset_rebase &&
+   git rebase $* b e &&
+   test_cmp_rev e HEAD
+   "
+}
+test_run_rebase success ''
+test_run_rebase success -m
+test_run_rebase success -i
+test_run_rebase success -p
+
+test_run_rebase () {
+   result=$1
+   shift
+   test_expect_$result "rebase $* -f rewrites even if upstream is an 
ancestor" "
+   reset_rebase &&
+   git rebase $* -f b e &&
+   ! test_cmp_rev e HEAD &&
+   test_cmp_rev b HEAD~2 &&
+   test_linear_range 'd e' b..
+   "
+}
+test_run_rebase success ''
+test_run_rebase success -m
+test_run_rebase success -i
+test_run_rebase failure -p
+
+test_run_rebase () {
+   result=$1
+   shift
+   test_expect_$result "rebase $* fast-forwards from ancestor of upstream" 
"
+   reset_rebase &&
+   git rebase $* e b &&
+   test_cmp_rev e HEAD
+   "
+}
+test_run_rebase success ''
+test_run_rebase success -m
+test_run_rebase success -i
+test_run_rebase success -p
+
+test_done
-- 
1.8.3.497.g83fddbe

--
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 v6 7/7] tests: move test for rebase messages from t3400 to t3406

2013-06-06 Thread Martin von Zweigbergk
t3406 is supposed to test "messages from rebase operation", so let's
move tests in t3400 that fit that description into 3406. Most of the
functionality they tested, except for the messages, has now been
subsumed by t3420.

Signed-off-by: Martin von Zweigbergk 
---
 t/t3400-rebase.sh | 22 --
 t/t3406-rebase-message.sh | 22 ++
 2 files changed, 22 insertions(+), 22 deletions(-)

diff --git a/t/t3400-rebase.sh b/t/t3400-rebase.sh
index b436ef4..45a55e9 100755
--- a/t/t3400-rebase.sh
+++ b/t/t3400-rebase.sh
@@ -59,28 +59,6 @@ test_expect_success 'rebase against master' '
git rebase master
 '
 
-test_expect_success 'rebase against master twice' '
-   git rebase master >out &&
-   test_i18ngrep "Current branch my-topic-branch is up to date" out
-'
-
-test_expect_success 'rebase against master twice with --force' '
-   git rebase --force-rebase master >out &&
-   test_i18ngrep "Current branch my-topic-branch is up to date, rebase 
forced" out
-'
-
-test_expect_success 'rebase against master twice from another branch' '
-   git checkout my-topic-branch^ &&
-   git rebase master my-topic-branch >out &&
-   test_i18ngrep "Current branch my-topic-branch is up to date" out
-'
-
-test_expect_success 'rebase fast-forward to master' '
-   git checkout my-topic-branch^ &&
-   git rebase my-topic-branch >out &&
-   test_i18ngrep "Fast-forwarded HEAD to my-topic-branch" out
-'
-
 test_expect_success 'the rebase operation should not have destroyed author 
information' '
! (git log | grep "Author:" | grep "<>")
 '
diff --git a/t/t3406-rebase-message.sh b/t/t3406-rebase-message.sh
index fe8c27f..0392e36 100755
--- a/t/t3406-rebase-message.sh
+++ b/t/t3406-rebase-message.sh
@@ -30,6 +30,28 @@ test_expect_success 'rebase -m' '
test_cmp expect actual
 '
 
+test_expect_success 'rebase against master twice' '
+   git rebase master >out &&
+   test_i18ngrep "Current branch topic is up to date" out
+'
+
+test_expect_success 'rebase against master twice with --force' '
+   git rebase --force-rebase master >out &&
+   test_i18ngrep "Current branch topic is up to date, rebase forced" out
+'
+
+test_expect_success 'rebase against master twice from another branch' '
+   git checkout topic^ &&
+   git rebase master topic >out &&
+   test_i18ngrep "Current branch topic is up to date" out
+'
+
+test_expect_success 'rebase fast-forward to master' '
+   git checkout topic^ &&
+   git rebase topic >out &&
+   test_i18ngrep "Fast-forwarded HEAD to topic" out
+'
+
 test_expect_success 'rebase --stat' '
git reset --hard start &&
 git rebase --stat master >diffstat.txt &&
-- 
1.8.3.497.g83fddbe

--
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 v6 4/7] add tests for rebasing root

2013-06-06 Thread Martin von Zweigbergk
Signed-off-by: Martin von Zweigbergk 
---
 t/t3421-rebase-topology-linear.sh | 129 ++
 1 file changed, 129 insertions(+)

diff --git a/t/t3421-rebase-topology-linear.sh 
b/t/t3421-rebase-topology-linear.sh
index f19f0d0..e67add6 100755
--- a/t/t3421-rebase-topology-linear.sh
+++ b/t/t3421-rebase-topology-linear.sh
@@ -218,4 +218,133 @@ test_run_rebase failure -m
 test_run_rebase failure -i
 test_run_rebase failure -p
 
+#   m
+#  /
+# a---b---c---g
+#
+# x---y---B
+#
+# uppercase = cherry-picked
+# m = reverted b
+#
+# Reverted patches are there for tests to be able to check if a commit
+# that introduced the same change as another commit is
+# dropped. Without reverted commits, we could get false positives
+# because applying the patch succeeds, but simply results in no
+# changes.
+test_expect_success 'setup of linear history for test involving root' '
+   git checkout b &&
+   revert m b &&
+   git checkout --orphan disjoint &&
+   git rm -rf . &&
+   test_commit x &&
+   test_commit y &&
+   cherry_pick B b
+'
+
+test_run_rebase () {
+   result=$1
+   shift
+   test_expect_$result "rebase $* --onto --root" "
+   reset_rebase &&
+   git rebase $* --onto c --root y &&
+   test_cmp_rev c HEAD~2 &&
+   test_linear_range 'x y' c..
+   "
+}
+test_run_rebase success ''
+test_run_rebase failure -m
+test_run_rebase success -i
+test_run_rebase success -p
+
+test_run_rebase () {
+   result=$1
+   shift
+   test_expect_$result "rebase $* without --onto --root with disjoint 
history" "
+   reset_rebase &&
+   git rebase $* c y &&
+   test_cmp_rev c HEAD~2 &&
+   test_linear_range 'x y' c..
+   "
+}
+test_run_rebase success ''
+test_run_rebase failure -m
+test_run_rebase success -i
+test_run_rebase failure -p
+
+test_run_rebase () {
+   result=$1
+   shift
+   test_expect_$result "rebase $* --onto --root drops patch in onto" "
+   reset_rebase &&
+   git rebase $* --onto m --root B &&
+   test_cmp_rev m HEAD~2 &&
+   test_linear_range 'x y' m..
+   "
+}
+test_run_rebase success ''
+test_run_rebase failure -m
+test_run_rebase success -i
+test_run_rebase success -p
+
+test_run_rebase () {
+   result=$1
+   shift
+   test_expect_$result "rebase $* --onto --root with merge-base does not 
go to root" "
+   reset_rebase &&
+   git rebase $* --onto m --root g &&
+   test_cmp_rev m HEAD~2 &&
+   test_linear_range 'c g' m..
+   "
+}
+
+test_run_rebase success ''
+test_run_rebase success -m
+test_run_rebase success -i
+test_run_rebase failure -p
+
+test_run_rebase () {
+   result=$1
+   shift
+   test_expect_$result "rebase $* without --onto --root with disjoint 
history drops patch in onto" "
+   reset_rebase &&
+   git rebase $* m B &&
+   test_cmp_rev m HEAD~2 &&
+   test_linear_range 'x y' m..
+   "
+}
+test_run_rebase success ''
+test_run_rebase failure -m
+test_run_rebase success -i
+test_run_rebase failure -p
+
+test_run_rebase () {
+   result=$1
+   shift
+   test_expect_$result "rebase $* --root on linear history is a no-op" "
+   reset_rebase &&
+   git rebase $* --root c &&
+   test_cmp_rev c HEAD
+   "
+}
+test_run_rebase failure ''
+test_run_rebase failure -m
+test_run_rebase failure -i
+test_run_rebase failure -p
+
+test_run_rebase () {
+   result=$1
+   shift
+   test_expect_$result "rebase $* -f --root on linear history causes 
re-write" "
+   reset_rebase &&
+   git rebase $* -f --root c &&
+   ! test_cmp_rev a HEAD~2 &&
+   test_linear_range 'a b c' HEAD
+   "
+}
+test_run_rebase success ''
+test_run_rebase success -m
+test_run_rebase success -i
+test_run_rebase success -p
+
 test_done
-- 
1.8.3.497.g83fddbe

--
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 v6 3/7] add tests for rebasing of empty commits

2013-06-06 Thread Martin von Zweigbergk
Signed-off-by: Martin von Zweigbergk 
---
 t/t3401-rebase-partial.sh | 24 
 t/t3421-rebase-topology-linear.sh | 58 +++
 2 files changed, 58 insertions(+), 24 deletions(-)

diff --git a/t/t3401-rebase-partial.sh b/t/t3401-rebase-partial.sh
index 58f4823..7ba1797 100755
--- a/t/t3401-rebase-partial.sh
+++ b/t/t3401-rebase-partial.sh
@@ -42,28 +42,4 @@ test_expect_success 'rebase --merge topic branch that was 
partially merged upstr
test_path_is_missing .git/rebase-merge
 '
 
-test_expect_success 'rebase ignores empty commit' '
-   git reset --hard A &&
-   git commit --allow-empty -m empty &&
-   test_commit D &&
-   git rebase C &&
-   test "$(git log --format=%s C..)" = "D"
-'
-
-test_expect_success 'rebase --keep-empty' '
-   git reset --hard D &&
-   git rebase --keep-empty C &&
-   test "$(git log --format=%s C..)" = "D
-empty"
-'
-
-test_expect_success 'rebase --keep-empty keeps empty even if already in 
upstream' '
-   git reset --hard A &&
-   git commit --allow-empty -m also-empty &&
-   git rebase --keep-empty D &&
-   test "$(git log --format=%s A..)" = "also-empty
-D
-empty"
-'
-
 test_done
diff --git a/t/t3421-rebase-topology-linear.sh 
b/t/t3421-rebase-topology-linear.sh
index ddcbfc6..f19f0d0 100755
--- a/t/t3421-rebase-topology-linear.sh
+++ b/t/t3421-rebase-topology-linear.sh
@@ -160,4 +160,62 @@ test_run_rebase success -m
 test_run_rebase success -i
 test_run_rebase success -p
 
+# a---b---c---j!
+#  \
+#   d---k!--l
+#
+# ! = empty
+test_expect_success 'setup of linear history for empty commit tests' '
+   git checkout c &&
+   make_empty j &&
+   git checkout d &&
+   make_empty k &&
+   test_commit l
+'
+
+test_run_rebase () {
+   result=$1
+   shift
+   test_expect_$result "rebase $* drops empty commit" "
+   reset_rebase &&
+   git rebase $* c l &&
+   test_cmp_rev c HEAD~2 &&
+   test_linear_range 'd l' c..
+   "
+}
+test_run_rebase success ''
+test_run_rebase success -m
+test_run_rebase success -i
+test_run_rebase success -p
+
+test_run_rebase () {
+   result=$1
+   shift
+   test_expect_$result "rebase $* --keep-empty" "
+   reset_rebase &&
+   git rebase $* --keep-empty c l &&
+   test_cmp_rev c HEAD~3 &&
+   test_linear_range 'd k l' c..
+   "
+}
+test_run_rebase success ''
+test_run_rebase failure -m
+test_run_rebase success -i
+test_run_rebase failure -p
+
+test_run_rebase () {
+   result=$1
+   shift
+   test_expect_$result "rebase $* --keep-empty keeps empty even if already 
in upstream" "
+   reset_rebase &&
+   git rebase $* --keep-empty j l &&
+   test_cmp_rev j HEAD~3 &&
+   test_linear_range 'd k l' j..
+   "
+}
+test_run_rebase success ''
+test_run_rebase failure -m
+test_run_rebase failure -i
+test_run_rebase failure -p
+
 test_done
-- 
1.8.3.497.g83fddbe

--
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 v5 5/7] add tests for rebasing merged history

2013-06-04 Thread Martin von Zweigbergk
On Tue, Jun 4, 2013 at 10:18 AM, Junio C Hamano  wrote:
> Martin von Zweigbergk  writes:
>
>> ---
>> +#TODO: make all flavors of rebase use --topo-order
>> +test_run_rebase success 'e n o' ''
>> +test_run_rebase success 'e n o' -m
>> +test_run_rebase success 'n o e' -i
>
> I do not quite follow this TODO.
>
> While I think it would be nice to update "rebase" so that all
> variants consider replaying the commits in the same order, in this
> history you have:
>
> +# a---b---c
> +#  \   \
> +#   d---e   \
> +#\   \   \
> +# n---o---w---v
> +#  \
> +#   z
>
> as long as o comes after n and e is shown before n or after o, which
> all three expected results satisify, it is in --topo-order, isn't it?

True, the TODO was too specific. I intended to get the list of commits
to rebase for all kinds of rebase by using 'git rev-list
--topo-order', but it doesn't really matter how the order is decided;
my goal was just to make it consistent. I'll update the TODOs.

>> +test_expect_success "rebase -p re-creates merge from side branch" "
>> + reset_rebase &&
>> + git rebase -p z w &&
>> + test_cmp_rev z HEAD^ &&
>> + test_cmp_rev w^2 HEAD^2
>> +"
>
> Hmm, turning the left one to the right one?
>
> +#   d---e   d---e
> +#\   \   \   \
> +# n---o---w ===>  n---o   \
> +#  \   \   \
> +#   z   z---W
>
> If w were a merge of o into e (i.e. w^1 were e not o), what should
> happen?  Would we get the same topology?

Yes, it seems like it does yield the same topology. That seems to be
what I tested at first. Search for "wrong" in [1]. I think Johannes's
point was that it was not realistic, not that he's against it working
in the same way independent of parent order. I don't feel strongly on
whether to include a test for each direction. Unless others do, I
guess I'll leave it as is. (But I did add a test case just now to see,
so it's very little work for me if someone does want it included.)

> In other words, when asked to replay w on top of z, how would we
> decide which parent to keep (in this case, e is kept)?

Keep any parent that is not an ancestor of the new base? Or something like that.


  [1] http://thread.gmane.org/gmane.comp.version-control.git/205796/focus=205806
--
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 v5 1/7] add simple tests of consistency across rebase types

2013-06-04 Thread Martin von Zweigbergk
On Mon, Jun 3, 2013 at 11:15 PM, Johannes Sixt  wrote:
> Am 6/4/2013 7:14, schrieb Martin von Zweigbergk:
>> On Mon, Jun 3, 2013 at 3:28 PM, Junio C Hamano  wrote:
>>>> +
>>>> +# checks that the revisions in "$2" represent a linear range with the
>>>> +# subjects in "$1"
>>>> +test_linear_range () {
>>>> + ! { git log --format=%p "$2" | sane_grep " " ;} &&
>>>
>>> An interesting way to spell:
>>>
>>> test $(git rev-list --merges "$2" | wc -l) = 0
>>
>> Heh, true. I'll change that.
>
> Then I think it would be even better written as
>
> revlist_merges=$(git rev-list --merges "$2") &&
> test -z "$revlist_merges"
>
> so as not to ignore errors in the git invocation (and at least one less
> fork()).

Done. I'll send it out in a day or two.
--
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 v5 1/7] add simple tests of consistency across rebase types

2013-06-03 Thread Martin von Zweigbergk
On Mon, Jun 3, 2013 at 3:28 PM, Junio C Hamano  wrote:
>> +
>> +# checks that the revisions in "$2" represent a linear range with the
>> +# subjects in "$1"
>> +test_linear_range () {
>> + ! { git log --format=%p "$2" | sane_grep " " ;} &&
>
> An interesting way to spell:
>
> test $(git rev-list --merges "$2" | wc -l) = 0

Heh, true. I'll change that. ("My" version was based on the one in
git-rebase.sh, around line 495.)

>> +reset_rebase () {
>> + git rebase --abort # may fail; ignore exit code
>
> test_might_fail to catch unusual exit codes?

Will change.

>> +# a---b---c
>> +#  \
>> +#   d---e

>> +test_run_rebase () {
>> + result=$1
>> + shift
>> + test_expect_$result "rebase $* fast-forwards if an ancestor of 
>> upstream" "
>
> The description is a non-sentence, and while I can tell what it
> wants to say, I do not have a good suggestion for rephrasing this.

Changing description to "... fast-forwards from an ancestor of upstream".

> This is asking to rebase the history leading to b on top of e, but e
> already includes everything in b, so it just turns into a no-op of
> not moving from e.  So it is not even a fast-forward.
>
>> + reset_rebase &&
>> + git rebase $* e b &&
>> + test_cmp_rev e HEAD

Well, "git rebase e b" is of course a kind of short form of "git
checkout b && git rebase e". While it's true that the implementation
doesn't bother checking out b first, that's just an optimization, but
let me know if you meant something else.

Thanks. Will wait another day or two for further comments before I
send another version.
--
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 v5 5/7] add tests for rebasing merged history

2013-06-03 Thread Martin von Zweigbergk
---
 t/t3400-rebase.sh |  31 +
 t/t3401-rebase-partial.sh |  45 ---
 t/t3404-rebase-interactive.sh |  10 +-
 t/t3409-rebase-preserve-merges.sh |  53 
 t/t3425-rebase-topology-merges.sh | 258 ++
 5 files changed, 260 insertions(+), 137 deletions(-)
 delete mode 100755 t/t3401-rebase-partial.sh
 create mode 100755 t/t3425-rebase-topology-merges.sh

diff --git a/t/t3400-rebase.sh b/t/t3400-rebase.sh
index b58fa1a..b436ef4 100755
--- a/t/t3400-rebase.sh
+++ b/t/t3400-rebase.sh
@@ -40,13 +40,6 @@ test_expect_success 'prepare repository with topic branches' 
'
echo Side >>C &&
git add C &&
git commit -m "Add C" &&
-   git checkout -b nonlinear my-topic-branch &&
-   echo Edit >>B &&
-   git add B &&
-   git commit -m "Modify B" &&
-   git merge side &&
-   git checkout -b upstream-merged-nonlinear &&
-   git merge master &&
git checkout -f my-topic-branch &&
git tag topic
 '
@@ -106,31 +99,9 @@ test_expect_success 'rebase from ambiguous branch name' '
git rebase master
 '
 
-test_expect_success 'rebase after merge master' '
-   git checkout --detach refs/tags/topic &&
-   git branch -D topic &&
-   git reset --hard topic &&
-   git merge master &&
-   git rebase master &&
-   ! (git show | grep "^Merge:")
-'
-
-test_expect_success 'rebase of history with merges is linearized' '
-   git checkout nonlinear &&
-   test 4 = $(git rev-list master.. | wc -l) &&
-   git rebase master &&
-   test 3 = $(git rev-list master.. | wc -l)
-'
-
-test_expect_success 'rebase of history with merges after upstream merge is 
linearized' '
-   git checkout upstream-merged-nonlinear &&
-   test 5 = $(git rev-list master.. | wc -l) &&
-   git rebase master &&
-   test 3 = $(git rev-list master.. | wc -l)
-'
-
 test_expect_success 'rebase a single mode change' '
git checkout master &&
+   git branch -D topic &&
echo 1 >X &&
git add X &&
test_tick &&
diff --git a/t/t3401-rebase-partial.sh b/t/t3401-rebase-partial.sh
deleted file mode 100755
index 7ba1797..000
--- a/t/t3401-rebase-partial.sh
+++ /dev/null
@@ -1,45 +0,0 @@
-#!/bin/sh
-#
-# Copyright (c) 2006 Yann Dirson, based on t3400 by Amos Waterland
-#
-
-test_description='git rebase should detect patches integrated upstream
-
-This test cherry-picks one local change of two into master branch, and
-checks that git rebase succeeds with only the second patch in the
-local branch.
-'
-. ./test-lib.sh
-
-test_expect_success 'prepare repository with topic branch' '
-   test_commit A &&
-   git checkout -b my-topic-branch &&
-   test_commit B &&
-   test_commit C &&
-   git checkout -f master &&
-   test_commit A2 A.t
-'
-
-test_expect_success 'pick top patch from topic branch into master' '
-   git cherry-pick C &&
-   git checkout -f my-topic-branch
-'
-
-test_debug '
-   git cherry master &&
-   git format-patch -k --stdout --full-index master >/dev/null &&
-   gitk --all & sleep 1
-'
-
-test_expect_success 'rebase topic branch against new master and check git am 
did not get halted' '
-   git rebase master &&
-   test_path_is_missing .git/rebase-apply
-'
-
-test_expect_success 'rebase --merge topic branch that was partially merged 
upstream' '
-   git reset --hard C &&
-   git rebase --merge master &&
-   test_path_is_missing .git/rebase-merge
-'
-
-test_done
diff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh
index a58406d..ffcaf02 100755
--- a/t/t3404-rebase-interactive.sh
+++ b/t/t3404-rebase-interactive.sh
@@ -477,19 +477,11 @@ test_expect_success 'interrupted squash works as expected 
(case 2)' '
test $one = $(git rev-parse HEAD~2)
 '
 
-test_expect_success 'ignore patch if in upstream' '
-   HEAD=$(git rev-parse HEAD) &&
-   git checkout -b has-cherry-picked HEAD^ &&
+test_expect_success '--continue tries to commit, even for "edit"' '
echo unrelated > file7 &&
git add file7 &&
test_tick &&
git commit -m "unrelated change" &&
-   git cherry-pick $HEAD &&
-   EXPECT_COUNT=1 git rebase -i $HEAD &&
-   test $HEAD = $(git rev-parse HEAD^)
-'
-
-test_expect_success '--continue tries to commit, even for "edit"' '
parent=$(git rev-parse HEAD^) &&
test_tick &&
FAKE_LINES="edit 1" git rebase -i HEAD^ &&
diff --git a/t/t3409-rebase-preserve-merges.sh 
b/t/t3409-rebase-preserve-merges.sh
index 6de4e22..2e0c364 100755
--- a/t/t3409-rebase-preserve-merges.sh
+++ b/t/t3409-rebase-preserve-merges.sh
@@ -11,14 +11,6 @@ Run "git rebase -p" and check that merges are properly 
carried along
 GIT_AUTHOR_EMAIL=bogus_email_address
 export GIT_AUTHOR_EMAIL
 
-# Clone 1 (trivial merge):
-#
-# A1--A2  <-- origin/master
-#  \   \
-#   B1--M  <-- topic
-#\
-# B2  <-- origin/topic
-#
 #

[PATCH v5 1/7] add simple tests of consistency across rebase types

2013-06-03 Thread Martin von Zweigbergk
Helped-by: Johannes Sixt 
---
 t/lib-rebase.sh   | 15 
 t/t3421-rebase-topology-linear.sh | 78 +++
 2 files changed, 93 insertions(+)
 create mode 100755 t/t3421-rebase-topology-linear.sh

diff --git a/t/lib-rebase.sh b/t/lib-rebase.sh
index 6ccf797..62b3887 100644
--- a/t/lib-rebase.sh
+++ b/t/lib-rebase.sh
@@ -65,3 +65,18 @@ EOF
test_set_editor "$(pwd)/fake-editor.sh"
chmod a+x fake-editor.sh
 }
+
+# checks that the revisions in "$2" represent a linear range with the
+# subjects in "$1"
+test_linear_range () {
+   ! { git log --format=%p "$2" | sane_grep " " ;} &&
+   expected=$1
+   set -- $(git log --reverse --format=%s "$2")
+   test "$expected" = "$*"
+}
+
+reset_rebase () {
+   git rebase --abort # may fail; ignore exit code
+   git reset --hard &&
+   git clean -f
+}
diff --git a/t/t3421-rebase-topology-linear.sh 
b/t/t3421-rebase-topology-linear.sh
new file mode 100755
index 000..c4b32db
--- /dev/null
+++ b/t/t3421-rebase-topology-linear.sh
@@ -0,0 +1,78 @@
+#!/bin/sh
+
+test_description='basic rebase topology tests'
+. ./test-lib.sh
+. "$TEST_DIRECTORY"/lib-rebase.sh
+
+# a---b---c
+#  \
+#   d---e
+test_expect_success 'setup' '
+   test_commit a &&
+   test_commit b &&
+   test_commit c &&
+   git checkout b &&
+   test_commit d &&
+   test_commit e
+'
+
+test_run_rebase () {
+   result=$1
+   shift
+   test_expect_$result "simple rebase $*" "
+   reset_rebase &&
+   git rebase $* c e &&
+   test_cmp_rev c HEAD~2 &&
+   test_linear_range 'd e' c..
+   "
+}
+test_run_rebase success ''
+test_run_rebase success -m
+test_run_rebase success -i
+test_run_rebase success -p
+
+test_run_rebase () {
+   result=$1
+   shift
+   test_expect_$result "rebase $* is no-op if upstream is an ancestor" "
+   reset_rebase &&
+   git rebase $* b e &&
+   test_cmp_rev e HEAD
+   "
+}
+test_run_rebase success ''
+test_run_rebase success -m
+test_run_rebase success -i
+test_run_rebase success -p
+
+test_run_rebase () {
+   result=$1
+   shift
+   test_expect_$result "rebase $* -f rewrites even if upstream is an 
ancestor" "
+   reset_rebase &&
+   git rebase $* -f b e &&
+   ! test_cmp_rev e HEAD &&
+   test_cmp_rev b HEAD~2 &&
+   test_linear_range 'd e' b..
+   "
+}
+test_run_rebase success ''
+test_run_rebase success -m
+test_run_rebase success -i
+test_run_rebase failure -p
+
+test_run_rebase () {
+   result=$1
+   shift
+   test_expect_$result "rebase $* fast-forwards if an ancestor of 
upstream" "
+   reset_rebase &&
+   git rebase $* e b &&
+   test_cmp_rev e HEAD
+   "
+}
+test_run_rebase success ''
+test_run_rebase success -m
+test_run_rebase success -i
+test_run_rebase success -p
+
+test_done
-- 
1.8.3.497.g83fddbe

--
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 v5 7/7] tests: move test for rebase messages from t3400 to t3406

2013-06-03 Thread Martin von Zweigbergk
t3406 is supposed to test "messages from rebase operation", so let's
move tests in t3400 that fit that description into 3406. Most of the
functionality they tested, except for the messages, has now been
subsumed by t3420.
---
 t/t3400-rebase.sh | 22 --
 t/t3406-rebase-message.sh | 22 ++
 2 files changed, 22 insertions(+), 22 deletions(-)

diff --git a/t/t3400-rebase.sh b/t/t3400-rebase.sh
index b436ef4..45a55e9 100755
--- a/t/t3400-rebase.sh
+++ b/t/t3400-rebase.sh
@@ -59,28 +59,6 @@ test_expect_success 'rebase against master' '
git rebase master
 '
 
-test_expect_success 'rebase against master twice' '
-   git rebase master >out &&
-   test_i18ngrep "Current branch my-topic-branch is up to date" out
-'
-
-test_expect_success 'rebase against master twice with --force' '
-   git rebase --force-rebase master >out &&
-   test_i18ngrep "Current branch my-topic-branch is up to date, rebase 
forced" out
-'
-
-test_expect_success 'rebase against master twice from another branch' '
-   git checkout my-topic-branch^ &&
-   git rebase master my-topic-branch >out &&
-   test_i18ngrep "Current branch my-topic-branch is up to date" out
-'
-
-test_expect_success 'rebase fast-forward to master' '
-   git checkout my-topic-branch^ &&
-   git rebase my-topic-branch >out &&
-   test_i18ngrep "Fast-forwarded HEAD to my-topic-branch" out
-'
-
 test_expect_success 'the rebase operation should not have destroyed author 
information' '
! (git log | grep "Author:" | grep "<>")
 '
diff --git a/t/t3406-rebase-message.sh b/t/t3406-rebase-message.sh
index fe8c27f..0392e36 100755
--- a/t/t3406-rebase-message.sh
+++ b/t/t3406-rebase-message.sh
@@ -30,6 +30,28 @@ test_expect_success 'rebase -m' '
test_cmp expect actual
 '
 
+test_expect_success 'rebase against master twice' '
+   git rebase master >out &&
+   test_i18ngrep "Current branch topic is up to date" out
+'
+
+test_expect_success 'rebase against master twice with --force' '
+   git rebase --force-rebase master >out &&
+   test_i18ngrep "Current branch topic is up to date, rebase forced" out
+'
+
+test_expect_success 'rebase against master twice from another branch' '
+   git checkout topic^ &&
+   git rebase master topic >out &&
+   test_i18ngrep "Current branch topic is up to date" out
+'
+
+test_expect_success 'rebase fast-forward to master' '
+   git checkout topic^ &&
+   git rebase topic >out &&
+   test_i18ngrep "Fast-forwarded HEAD to topic" out
+'
+
 test_expect_success 'rebase --stat' '
git reset --hard start &&
 git rebase --stat master >diffstat.txt &&
-- 
1.8.3.497.g83fddbe

--
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 v5 4/7] add tests for rebasing root

2013-06-03 Thread Martin von Zweigbergk
---
 t/t3421-rebase-topology-linear.sh | 129 ++
 1 file changed, 129 insertions(+)

diff --git a/t/t3421-rebase-topology-linear.sh 
b/t/t3421-rebase-topology-linear.sh
index 81e3d59..659a7b3 100755
--- a/t/t3421-rebase-topology-linear.sh
+++ b/t/t3421-rebase-topology-linear.sh
@@ -218,4 +218,133 @@ test_run_rebase failure -m
 test_run_rebase failure -i
 test_run_rebase failure -p
 
+#   m
+#  /
+# a---b---c---g
+#
+# x---y---B
+#
+# uppercase = cherry-picked
+# m = reverted b
+#
+# Reverted patches are there for tests to be able to check if a commit
+# that introduced the same change as another commit is
+# dropped. Without reverted commits, we could get false positives
+# because applying the patch succeeds, but simply results in no
+# changes.
+test_expect_success 'setup of linear history for test involving root' '
+   git checkout b &&
+   revert m b &&
+   git checkout --orphan disjoint &&
+   git rm -rf . &&
+   test_commit x &&
+   test_commit y &&
+   cherry_pick B b
+'
+
+test_run_rebase () {
+   result=$1
+   shift
+   test_expect_$result "rebase $* --onto --root" "
+   reset_rebase &&
+   git rebase $* --onto c --root y &&
+   test_cmp_rev c HEAD~2 &&
+   test_linear_range 'x y' c..
+   "
+}
+test_run_rebase success ''
+test_run_rebase failure -m
+test_run_rebase success -i
+test_run_rebase success -p
+
+test_run_rebase () {
+   result=$1
+   shift
+   test_expect_$result "rebase $* without --onto --root with disjoint 
history" "
+   reset_rebase &&
+   git rebase $* c y &&
+   test_cmp_rev c HEAD~2 &&
+   test_linear_range 'x y' c..
+   "
+}
+test_run_rebase success ''
+test_run_rebase failure -m
+test_run_rebase success -i
+test_run_rebase failure -p
+
+test_run_rebase () {
+   result=$1
+   shift
+   test_expect_$result "rebase $* --onto --root drops patch in onto" "
+   reset_rebase &&
+   git rebase $* --onto m --root B &&
+   test_cmp_rev m HEAD~2 &&
+   test_linear_range 'x y' m..
+   "
+}
+test_run_rebase success ''
+test_run_rebase failure -m
+test_run_rebase success -i
+test_run_rebase success -p
+
+test_run_rebase () {
+   result=$1
+   shift
+   test_expect_$result "rebase $* --onto --root with merge-base does not 
go to root" "
+   reset_rebase &&
+   git rebase $* --onto m --root g &&
+   test_cmp_rev m HEAD~2 &&
+   test_linear_range 'c g' m..
+   "
+}
+
+test_run_rebase success ''
+test_run_rebase success -m
+test_run_rebase success -i
+test_run_rebase failure -p
+
+test_run_rebase () {
+   result=$1
+   shift
+   test_expect_$result "rebase $* without --onto --root with disjoint 
history drops patch in onto" "
+   reset_rebase &&
+   git rebase $* m B &&
+   test_cmp_rev m HEAD~2 &&
+   test_linear_range 'x y' m..
+   "
+}
+test_run_rebase success ''
+test_run_rebase failure -m
+test_run_rebase success -i
+test_run_rebase failure -p
+
+test_run_rebase () {
+   result=$1
+   shift
+   test_expect_$result "rebase $* --root on linear history is a no-op" "
+   reset_rebase &&
+   git rebase $* --root c &&
+   test_cmp_rev c HEAD
+   "
+}
+test_run_rebase failure ''
+test_run_rebase failure -m
+test_run_rebase failure -i
+test_run_rebase failure -p
+
+test_run_rebase () {
+   result=$1
+   shift
+   test_expect_$result "rebase $* -f --root on linear history causes 
re-write" "
+   reset_rebase &&
+   git rebase $* -f --root c &&
+   ! test_cmp_rev a HEAD~2 &&
+   test_linear_range 'a b c' HEAD
+   "
+}
+test_run_rebase success ''
+test_run_rebase success -m
+test_run_rebase success -i
+test_run_rebase success -p
+
 test_done
-- 
1.8.3.497.g83fddbe

--
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 v5 6/7] t3406: modernize style

2013-06-03 Thread Martin von Zweigbergk
Update the following:

 - Quote 'setup'
 - Remove blank lines within test case body
 - Use test_commit instead of custom quick_one
 - Create branch "topic" from tag created by test_commit
---
 t/t3406-rebase-message.sh | 30 +-
 1 file changed, 9 insertions(+), 21 deletions(-)

diff --git a/t/t3406-rebase-message.sh b/t/t3406-rebase-message.sh
index e6a9a0d..fe8c27f 100755
--- a/t/t3406-rebase-message.sh
+++ b/t/t3406-rebase-message.sh
@@ -4,27 +4,17 @@ test_description='messages from rebase operation'
 
 . ./test-lib.sh
 
-quick_one () {
-   echo "$1" >"file$1" &&
-   git add "file$1" &&
-   test_tick &&
-   git commit -m "$1"
-}
+test_expect_success 'setup' '
+   test_commit O fileO &&
+   test_commit X fileX &&
+   test_commit A fileA &&
+   test_commit B fileB &&
+   test_commit Y fileY &&
 
-test_expect_success setup '
-   quick_one O &&
-   git branch topic &&
-   quick_one X &&
-   quick_one A &&
-   quick_one B &&
-   quick_one Y &&
-
-   git checkout topic &&
-   quick_one A &&
-   quick_one B &&
-   quick_one Z &&
+   git checkout -b topic O &&
+   git cherry-pick A B &&
+   test_commit Z fileZ &&
git tag start
-
 '
 
 cat >expect <<\EOF
@@ -34,12 +24,10 @@ Committed: 0003 Z
 EOF
 
 test_expect_success 'rebase -m' '
-
git rebase -m master >report &&
sed -n -e "/^Already applied: /p" \
-e "/^Committed: /p" report >actual &&
test_cmp expect actual
-
 '
 
 test_expect_success 'rebase --stat' '
-- 
1.8.3.497.g83fddbe

--
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 v5 2/7] add tests for rebasing with patch-equivalence present

2013-06-03 Thread Martin von Zweigbergk
---
 t/lib-rebase.sh   | 17 
 t/t3421-rebase-topology-linear.sh | 85 +++
 2 files changed, 102 insertions(+)

diff --git a/t/lib-rebase.sh b/t/lib-rebase.sh
index 62b3887..16eeb1c 100644
--- a/t/lib-rebase.sh
+++ b/t/lib-rebase.sh
@@ -80,3 +80,20 @@ reset_rebase () {
git reset --hard &&
git clean -f
 }
+
+cherry_pick () {
+   git cherry-pick -n "$2" &&
+   git commit -m "$1" &&
+   git tag "$1"
+}
+
+revert () {
+   git revert -n "$2" &&
+   git commit -m "$1" &&
+   git tag "$1"
+}
+
+make_empty () {
+   git commit --allow-empty -m "$1" &&
+   git tag "$1"
+}
diff --git a/t/t3421-rebase-topology-linear.sh 
b/t/t3421-rebase-topology-linear.sh
index c4b32db..75cc476 100755
--- a/t/t3421-rebase-topology-linear.sh
+++ b/t/t3421-rebase-topology-linear.sh
@@ -75,4 +75,89 @@ test_run_rebase success -m
 test_run_rebase success -i
 test_run_rebase success -p
 
+#   f
+#  /
+# a---b---c---g---h
+#  \
+#   d---G---i
+#
+# uppercase = cherry-picked
+# h = reverted g
+#
+# Reverted patches are there for tests to be able to check if a commit
+# that introduced the same change as another commit is
+# dropped. Without reverted commits, we could get false positives
+# because applying the patch succeeds, but simply results in no
+# changes.
+test_expect_success 'setup of linear history for range selection tests' '
+   git checkout c &&
+   test_commit g &&
+   revert h g &&
+   git checkout d &&
+   cherry_pick G g &&
+   test_commit i &&
+   git checkout b &&
+   test_commit f
+'
+
+test_run_rebase () {
+   result=$1
+   shift
+   test_expect_$result "rebase $* drops patches in upstream" "
+   reset_rebase &&
+   git rebase $* h i &&
+   test_cmp_rev h HEAD~2 &&
+   test_linear_range 'd i' h..
+   "
+}
+test_run_rebase success ''
+test_run_rebase failure -m
+test_run_rebase success -i
+test_run_rebase success -p
+
+test_run_rebase () {
+   result=$1
+   shift
+   test_expect_$result "rebase $* can drop last patch if in upstream" "
+   reset_rebase &&
+   git rebase $* h G &&
+   test_cmp_rev h HEAD^ &&
+   test_linear_range 'd' h..
+   "
+}
+test_run_rebase success ''
+test_run_rebase failure -m
+test_run_rebase success -i
+test_run_rebase success -p
+
+test_run_rebase () {
+   result=$1
+   shift
+   test_expect_$result "rebase $* --onto drops patches in upstream" "
+   reset_rebase &&
+   git rebase $* --onto f h i &&
+   test_cmp_rev f HEAD~2 &&
+   test_linear_range 'd i' f..
+   "
+}
+test_run_rebase success ''
+test_run_rebase failure -m
+test_run_rebase success -i
+test_run_rebase success -p
+
+test_run_rebase () {
+   result=$1
+   shift
+   test_expect_$result "rebase $* --onto does not drop patches in onto" "
+   reset_rebase &&
+   git rebase $* --onto h f i &&
+   test_cmp_rev h HEAD~3 &&
+   test_linear_range 'd G i' h..
+   "
+}
+test_run_rebase success ''
+test_run_rebase success -m
+test_run_rebase success -i
+test_run_rebase success -p
+
 test_done
-- 
1.8.3.497.g83fddbe

--
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 v5 3/7] add tests for rebasing of empty commits

2013-06-03 Thread Martin von Zweigbergk
---
 t/t3401-rebase-partial.sh | 24 
 t/t3421-rebase-topology-linear.sh | 58 +++
 2 files changed, 58 insertions(+), 24 deletions(-)

diff --git a/t/t3401-rebase-partial.sh b/t/t3401-rebase-partial.sh
index 58f4823..7ba1797 100755
--- a/t/t3401-rebase-partial.sh
+++ b/t/t3401-rebase-partial.sh
@@ -42,28 +42,4 @@ test_expect_success 'rebase --merge topic branch that was 
partially merged upstr
test_path_is_missing .git/rebase-merge
 '
 
-test_expect_success 'rebase ignores empty commit' '
-   git reset --hard A &&
-   git commit --allow-empty -m empty &&
-   test_commit D &&
-   git rebase C &&
-   test "$(git log --format=%s C..)" = "D"
-'
-
-test_expect_success 'rebase --keep-empty' '
-   git reset --hard D &&
-   git rebase --keep-empty C &&
-   test "$(git log --format=%s C..)" = "D
-empty"
-'
-
-test_expect_success 'rebase --keep-empty keeps empty even if already in 
upstream' '
-   git reset --hard A &&
-   git commit --allow-empty -m also-empty &&
-   git rebase --keep-empty D &&
-   test "$(git log --format=%s A..)" = "also-empty
-D
-empty"
-'
-
 test_done
diff --git a/t/t3421-rebase-topology-linear.sh 
b/t/t3421-rebase-topology-linear.sh
index 75cc476..81e3d59 100755
--- a/t/t3421-rebase-topology-linear.sh
+++ b/t/t3421-rebase-topology-linear.sh
@@ -160,4 +160,62 @@ test_run_rebase success -m
 test_run_rebase success -i
 test_run_rebase success -p
 
+# a---b---c---j!
+#  \
+#   d---k!--l
+#
+# ! = empty
+test_expect_success 'setup of linear history for empty commit tests' '
+   git checkout c &&
+   make_empty j &&
+   git checkout d &&
+   make_empty k &&
+   test_commit l
+'
+
+test_run_rebase () {
+   result=$1
+   shift
+   test_expect_$result "rebase $* drops empty commit" "
+   reset_rebase &&
+   git rebase $* c l &&
+   test_cmp_rev c HEAD~2 &&
+   test_linear_range 'd l' c..
+   "
+}
+test_run_rebase success ''
+test_run_rebase success -m
+test_run_rebase success -i
+test_run_rebase success -p
+
+test_run_rebase () {
+   result=$1
+   shift
+   test_expect_$result "rebase $* --keep-empty" "
+   reset_rebase &&
+   git rebase $* --keep-empty c l &&
+   test_cmp_rev c HEAD~3 &&
+   test_linear_range 'd k l' c..
+   "
+}
+test_run_rebase success ''
+test_run_rebase failure -m
+test_run_rebase success -i
+test_run_rebase failure -p
+
+test_run_rebase () {
+   result=$1
+   shift
+   test_expect_$result "rebase $* --keep-empty keeps empty even if already 
in upstream" "
+   reset_rebase &&
+   git rebase $* --keep-empty j l &&
+   test_cmp_rev j HEAD~3 &&
+   test_linear_range 'd k l' j..
+   "
+}
+test_run_rebase success ''
+test_run_rebase failure -m
+test_run_rebase failure -i
+test_run_rebase failure -p
+
 test_done
-- 
1.8.3.497.g83fddbe

--
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 v5 0/7] Rebase topology test

2013-06-03 Thread Martin von Zweigbergk
The only change since v4 should be that t3420 was renamed t3421.

Martin von Zweigbergk (7):
  add simple tests of consistency across rebase types
  add tests for rebasing with patch-equivalence present
  add tests for rebasing of empty commits
  add tests for rebasing root
  add tests for rebasing merged history
  t3406: modernize style
  tests: move test for rebase messages from t3400 to t3406

 t/lib-rebase.sh   |  32 
 t/t3400-rebase.sh |  53 +-
 t/t3401-rebase-partial.sh |  69 
 t/t3404-rebase-interactive.sh |  10 +-
 t/t3406-rebase-message.sh |  50 +++---
 t/t3409-rebase-preserve-merges.sh |  53 --
 t/t3421-rebase-topology-linear.sh | 350 ++
 t/t3425-rebase-topology-merges.sh | 258 
 8 files changed, 672 insertions(+), 203 deletions(-)
 delete mode 100755 t/t3401-rebase-partial.sh
 create mode 100755 t/t3421-rebase-topology-linear.sh
 create mode 100755 t/t3425-rebase-topology-merges.sh

-- 
1.8.3.497.g83fddbe

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


Re: [PATCH v2 1/7] add simple tests of consistency across rebase types

2013-06-03 Thread Martin von Zweigbergk
On Mon, Jun 3, 2013 at 11:05 AM, Junio C Hamano  wrote:
> Martin von Zweigbergk  writes:
>
>> On Tue, May 28, 2013 at 11:39 PM, Martin von Zweigbergk
>>  wrote:
>>>  create mode 100755 t/t3420-rebase-topology-linear.sh
>>
>> Just FYI, there's another test case with the same number
>> (t3420-rebase-autostash) in pu. I don't know how you normally handle
>> such cases.
>
> Thanks for a heads-up.  Usually, the series that appears later on
> the list yields and finds a unique number.

In this case, that's my series. Want a resend or do you want to do it
yourself? I'm fine either way, whatever is easiest for you.
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2 1/7] add simple tests of consistency across rebase types

2013-06-03 Thread Martin von Zweigbergk
On Tue, May 28, 2013 at 11:39 PM, Martin von Zweigbergk
 wrote:
>  create mode 100755 t/t3420-rebase-topology-linear.sh

Just FYI, there's another test case with the same number
(t3420-rebase-autostash) in pu. I don't know how you normally handle
such cases.
--
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 v4 5/7] add tests for rebasing merged history

2013-06-01 Thread Martin von Zweigbergk
---

> The reason is that this check is incomplete:
>
>test_revision_subjects 'd i e u' HEAD~2 HEAD^2 HEAD^ HEAD

Nice catch! This should fix it. I couldn't use the method you
suggested because of how test_revision_subjects works (repeated
revisions are ignored), but this makes the check stricter anyway.

Junio, all the previous patches are unchanged since v3, so I'm not
resending them. Thanks.

 t/t3400-rebase.sh |  31 +
 t/t3401-rebase-partial.sh |  45 ---
 t/t3404-rebase-interactive.sh |  10 +-
 t/t3409-rebase-preserve-merges.sh |  53 
 t/t3425-rebase-topology-merges.sh | 258 ++
 5 files changed, 260 insertions(+), 137 deletions(-)
 delete mode 100755 t/t3401-rebase-partial.sh
 create mode 100755 t/t3425-rebase-topology-merges.sh

diff --git a/t/t3400-rebase.sh b/t/t3400-rebase.sh
index b58fa1a..b436ef4 100755
--- a/t/t3400-rebase.sh
+++ b/t/t3400-rebase.sh
@@ -40,13 +40,6 @@ test_expect_success 'prepare repository with topic branches' 
'
echo Side >>C &&
git add C &&
git commit -m "Add C" &&
-   git checkout -b nonlinear my-topic-branch &&
-   echo Edit >>B &&
-   git add B &&
-   git commit -m "Modify B" &&
-   git merge side &&
-   git checkout -b upstream-merged-nonlinear &&
-   git merge master &&
git checkout -f my-topic-branch &&
git tag topic
 '
@@ -106,31 +99,9 @@ test_expect_success 'rebase from ambiguous branch name' '
git rebase master
 '
 
-test_expect_success 'rebase after merge master' '
-   git checkout --detach refs/tags/topic &&
-   git branch -D topic &&
-   git reset --hard topic &&
-   git merge master &&
-   git rebase master &&
-   ! (git show | grep "^Merge:")
-'
-
-test_expect_success 'rebase of history with merges is linearized' '
-   git checkout nonlinear &&
-   test 4 = $(git rev-list master.. | wc -l) &&
-   git rebase master &&
-   test 3 = $(git rev-list master.. | wc -l)
-'
-
-test_expect_success 'rebase of history with merges after upstream merge is 
linearized' '
-   git checkout upstream-merged-nonlinear &&
-   test 5 = $(git rev-list master.. | wc -l) &&
-   git rebase master &&
-   test 3 = $(git rev-list master.. | wc -l)
-'
-
 test_expect_success 'rebase a single mode change' '
git checkout master &&
+   git branch -D topic &&
echo 1 >X &&
git add X &&
test_tick &&
diff --git a/t/t3401-rebase-partial.sh b/t/t3401-rebase-partial.sh
deleted file mode 100755
index 7ba1797..000
--- a/t/t3401-rebase-partial.sh
+++ /dev/null
@@ -1,45 +0,0 @@
-#!/bin/sh
-#
-# Copyright (c) 2006 Yann Dirson, based on t3400 by Amos Waterland
-#
-
-test_description='git rebase should detect patches integrated upstream
-
-This test cherry-picks one local change of two into master branch, and
-checks that git rebase succeeds with only the second patch in the
-local branch.
-'
-. ./test-lib.sh
-
-test_expect_success 'prepare repository with topic branch' '
-   test_commit A &&
-   git checkout -b my-topic-branch &&
-   test_commit B &&
-   test_commit C &&
-   git checkout -f master &&
-   test_commit A2 A.t
-'
-
-test_expect_success 'pick top patch from topic branch into master' '
-   git cherry-pick C &&
-   git checkout -f my-topic-branch
-'
-
-test_debug '
-   git cherry master &&
-   git format-patch -k --stdout --full-index master >/dev/null &&
-   gitk --all & sleep 1
-'
-
-test_expect_success 'rebase topic branch against new master and check git am 
did not get halted' '
-   git rebase master &&
-   test_path_is_missing .git/rebase-apply
-'
-
-test_expect_success 'rebase --merge topic branch that was partially merged 
upstream' '
-   git reset --hard C &&
-   git rebase --merge master &&
-   test_path_is_missing .git/rebase-merge
-'
-
-test_done
diff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh
index a58406d..ffcaf02 100755
--- a/t/t3404-rebase-interactive.sh
+++ b/t/t3404-rebase-interactive.sh
@@ -477,19 +477,11 @@ test_expect_success 'interrupted squash works as expected 
(case 2)' '
test $one = $(git rev-parse HEAD~2)
 '
 
-test_expect_success 'ignore patch if in upstream' '
-   HEAD=$(git rev-parse HEAD) &&
-   git checkout -b has-cherry-picked HEAD^ &&
+test_expect_success '--continue tries to commit, even for "edit"' '
echo unrelated > file7 &&
git add file7 &&
test_tick &&
git commit -m "unrelated change" &&
-   git cherry-pick $HEAD &&
-   EXPECT_COUNT=1 git rebase -i $HEAD &&
-   test $HEAD = $(git rev-parse HEAD^)
-'
-
-test_expect_success '--continue tries to commit, even for "edit"' '
parent=$(git rev-parse HEAD^) &&
test_tick &&
FAKE_LINES="edit 1" git rebase -i HEAD^ &&
diff --git a/t/t3409-rebase-preserve-merges.sh 
b/t/t3409-rebase-preserve-merges.s

[PATCH v3 6/7] t3406: modernize style

2013-05-30 Thread Martin von Zweigbergk
Update the following:

 - Quote 'setup'
 - Remove blank lines within test case body
 - Use test_commit instead of custom quick_one
 - Create branch "topic" from tag created by test_commit
---
 t/t3406-rebase-message.sh | 30 +-
 1 file changed, 9 insertions(+), 21 deletions(-)

diff --git a/t/t3406-rebase-message.sh b/t/t3406-rebase-message.sh
index e6a9a0d..fe8c27f 100755
--- a/t/t3406-rebase-message.sh
+++ b/t/t3406-rebase-message.sh
@@ -4,27 +4,17 @@ test_description='messages from rebase operation'
 
 . ./test-lib.sh
 
-quick_one () {
-   echo "$1" >"file$1" &&
-   git add "file$1" &&
-   test_tick &&
-   git commit -m "$1"
-}
+test_expect_success 'setup' '
+   test_commit O fileO &&
+   test_commit X fileX &&
+   test_commit A fileA &&
+   test_commit B fileB &&
+   test_commit Y fileY &&
 
-test_expect_success setup '
-   quick_one O &&
-   git branch topic &&
-   quick_one X &&
-   quick_one A &&
-   quick_one B &&
-   quick_one Y &&
-
-   git checkout topic &&
-   quick_one A &&
-   quick_one B &&
-   quick_one Z &&
+   git checkout -b topic O &&
+   git cherry-pick A B &&
+   test_commit Z fileZ &&
git tag start
-
 '
 
 cat >expect <<\EOF
@@ -34,12 +24,10 @@ Committed: 0003 Z
 EOF
 
 test_expect_success 'rebase -m' '
-
git rebase -m master >report &&
sed -n -e "/^Already applied: /p" \
-e "/^Committed: /p" report >actual &&
test_cmp expect actual
-
 '
 
 test_expect_success 'rebase --stat' '
-- 
1.8.2.674.gd17d3d2

--
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 7/7] tests: move test for rebase messages from t3400 to t3406

2013-05-30 Thread Martin von Zweigbergk
t3406 is supposed to test "messages from rebase operation", so let's
move tests in t3400 that fit that description into 3406. Most of the
functionality they tested, except for the messages, has now been
subsumed by t3420.
---
 t/t3400-rebase.sh | 22 --
 t/t3406-rebase-message.sh | 22 ++
 2 files changed, 22 insertions(+), 22 deletions(-)

diff --git a/t/t3400-rebase.sh b/t/t3400-rebase.sh
index b436ef4..45a55e9 100755
--- a/t/t3400-rebase.sh
+++ b/t/t3400-rebase.sh
@@ -59,28 +59,6 @@ test_expect_success 'rebase against master' '
git rebase master
 '
 
-test_expect_success 'rebase against master twice' '
-   git rebase master >out &&
-   test_i18ngrep "Current branch my-topic-branch is up to date" out
-'
-
-test_expect_success 'rebase against master twice with --force' '
-   git rebase --force-rebase master >out &&
-   test_i18ngrep "Current branch my-topic-branch is up to date, rebase 
forced" out
-'
-
-test_expect_success 'rebase against master twice from another branch' '
-   git checkout my-topic-branch^ &&
-   git rebase master my-topic-branch >out &&
-   test_i18ngrep "Current branch my-topic-branch is up to date" out
-'
-
-test_expect_success 'rebase fast-forward to master' '
-   git checkout my-topic-branch^ &&
-   git rebase my-topic-branch >out &&
-   test_i18ngrep "Fast-forwarded HEAD to my-topic-branch" out
-'
-
 test_expect_success 'the rebase operation should not have destroyed author 
information' '
! (git log | grep "Author:" | grep "<>")
 '
diff --git a/t/t3406-rebase-message.sh b/t/t3406-rebase-message.sh
index fe8c27f..0392e36 100755
--- a/t/t3406-rebase-message.sh
+++ b/t/t3406-rebase-message.sh
@@ -30,6 +30,28 @@ test_expect_success 'rebase -m' '
test_cmp expect actual
 '
 
+test_expect_success 'rebase against master twice' '
+   git rebase master >out &&
+   test_i18ngrep "Current branch topic is up to date" out
+'
+
+test_expect_success 'rebase against master twice with --force' '
+   git rebase --force-rebase master >out &&
+   test_i18ngrep "Current branch topic is up to date, rebase forced" out
+'
+
+test_expect_success 'rebase against master twice from another branch' '
+   git checkout topic^ &&
+   git rebase master topic >out &&
+   test_i18ngrep "Current branch topic is up to date" out
+'
+
+test_expect_success 'rebase fast-forward to master' '
+   git checkout topic^ &&
+   git rebase topic >out &&
+   test_i18ngrep "Fast-forwarded HEAD to topic" out
+'
+
 test_expect_success 'rebase --stat' '
git reset --hard start &&
 git rebase --stat master >diffstat.txt &&
-- 
1.8.2.674.gd17d3d2

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


[PATCH v3 5/7] add tests for rebasing merged history

2013-05-30 Thread Martin von Zweigbergk
---
 t/t3400-rebase.sh |  31 +
 t/t3401-rebase-partial.sh |  45 ---
 t/t3404-rebase-interactive.sh |  10 +-
 t/t3409-rebase-preserve-merges.sh |  53 
 t/t3425-rebase-topology-merges.sh | 252 ++
 5 files changed, 254 insertions(+), 137 deletions(-)
 delete mode 100755 t/t3401-rebase-partial.sh
 create mode 100755 t/t3425-rebase-topology-merges.sh

diff --git a/t/t3400-rebase.sh b/t/t3400-rebase.sh
index b58fa1a..b436ef4 100755
--- a/t/t3400-rebase.sh
+++ b/t/t3400-rebase.sh
@@ -40,13 +40,6 @@ test_expect_success 'prepare repository with topic branches' 
'
echo Side >>C &&
git add C &&
git commit -m "Add C" &&
-   git checkout -b nonlinear my-topic-branch &&
-   echo Edit >>B &&
-   git add B &&
-   git commit -m "Modify B" &&
-   git merge side &&
-   git checkout -b upstream-merged-nonlinear &&
-   git merge master &&
git checkout -f my-topic-branch &&
git tag topic
 '
@@ -106,31 +99,9 @@ test_expect_success 'rebase from ambiguous branch name' '
git rebase master
 '
 
-test_expect_success 'rebase after merge master' '
-   git checkout --detach refs/tags/topic &&
-   git branch -D topic &&
-   git reset --hard topic &&
-   git merge master &&
-   git rebase master &&
-   ! (git show | grep "^Merge:")
-'
-
-test_expect_success 'rebase of history with merges is linearized' '
-   git checkout nonlinear &&
-   test 4 = $(git rev-list master.. | wc -l) &&
-   git rebase master &&
-   test 3 = $(git rev-list master.. | wc -l)
-'
-
-test_expect_success 'rebase of history with merges after upstream merge is 
linearized' '
-   git checkout upstream-merged-nonlinear &&
-   test 5 = $(git rev-list master.. | wc -l) &&
-   git rebase master &&
-   test 3 = $(git rev-list master.. | wc -l)
-'
-
 test_expect_success 'rebase a single mode change' '
git checkout master &&
+   git branch -D topic &&
echo 1 >X &&
git add X &&
test_tick &&
diff --git a/t/t3401-rebase-partial.sh b/t/t3401-rebase-partial.sh
deleted file mode 100755
index 7ba1797..000
--- a/t/t3401-rebase-partial.sh
+++ /dev/null
@@ -1,45 +0,0 @@
-#!/bin/sh
-#
-# Copyright (c) 2006 Yann Dirson, based on t3400 by Amos Waterland
-#
-
-test_description='git rebase should detect patches integrated upstream
-
-This test cherry-picks one local change of two into master branch, and
-checks that git rebase succeeds with only the second patch in the
-local branch.
-'
-. ./test-lib.sh
-
-test_expect_success 'prepare repository with topic branch' '
-   test_commit A &&
-   git checkout -b my-topic-branch &&
-   test_commit B &&
-   test_commit C &&
-   git checkout -f master &&
-   test_commit A2 A.t
-'
-
-test_expect_success 'pick top patch from topic branch into master' '
-   git cherry-pick C &&
-   git checkout -f my-topic-branch
-'
-
-test_debug '
-   git cherry master &&
-   git format-patch -k --stdout --full-index master >/dev/null &&
-   gitk --all & sleep 1
-'
-
-test_expect_success 'rebase topic branch against new master and check git am 
did not get halted' '
-   git rebase master &&
-   test_path_is_missing .git/rebase-apply
-'
-
-test_expect_success 'rebase --merge topic branch that was partially merged 
upstream' '
-   git reset --hard C &&
-   git rebase --merge master &&
-   test_path_is_missing .git/rebase-merge
-'
-
-test_done
diff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh
index a58406d..ffcaf02 100755
--- a/t/t3404-rebase-interactive.sh
+++ b/t/t3404-rebase-interactive.sh
@@ -477,19 +477,11 @@ test_expect_success 'interrupted squash works as expected 
(case 2)' '
test $one = $(git rev-parse HEAD~2)
 '
 
-test_expect_success 'ignore patch if in upstream' '
-   HEAD=$(git rev-parse HEAD) &&
-   git checkout -b has-cherry-picked HEAD^ &&
+test_expect_success '--continue tries to commit, even for "edit"' '
echo unrelated > file7 &&
git add file7 &&
test_tick &&
git commit -m "unrelated change" &&
-   git cherry-pick $HEAD &&
-   EXPECT_COUNT=1 git rebase -i $HEAD &&
-   test $HEAD = $(git rev-parse HEAD^)
-'
-
-test_expect_success '--continue tries to commit, even for "edit"' '
parent=$(git rev-parse HEAD^) &&
test_tick &&
FAKE_LINES="edit 1" git rebase -i HEAD^ &&
diff --git a/t/t3409-rebase-preserve-merges.sh 
b/t/t3409-rebase-preserve-merges.sh
index 6de4e22..2e0c364 100755
--- a/t/t3409-rebase-preserve-merges.sh
+++ b/t/t3409-rebase-preserve-merges.sh
@@ -11,14 +11,6 @@ Run "git rebase -p" and check that merges are properly 
carried along
 GIT_AUTHOR_EMAIL=bogus_email_address
 export GIT_AUTHOR_EMAIL
 
-# Clone 1 (trivial merge):
-#
-# A1--A2  <-- origin/master
-#  \   \
-#   B1--M  <-- topic
-#\
-# B2  <-- origin/topic
-#
 #

[PATCH v3 4/7] add tests for rebasing root

2013-05-30 Thread Martin von Zweigbergk
---
 t/t3420-rebase-topology-linear.sh | 129 ++
 1 file changed, 129 insertions(+)

diff --git a/t/t3420-rebase-topology-linear.sh 
b/t/t3420-rebase-topology-linear.sh
index 81e3d59..659a7b3 100755
--- a/t/t3420-rebase-topology-linear.sh
+++ b/t/t3420-rebase-topology-linear.sh
@@ -218,4 +218,133 @@ test_run_rebase failure -m
 test_run_rebase failure -i
 test_run_rebase failure -p
 
+#   m
+#  /
+# a---b---c---g
+#
+# x---y---B
+#
+# uppercase = cherry-picked
+# m = reverted b
+#
+# Reverted patches are there for tests to be able to check if a commit
+# that introduced the same change as another commit is
+# dropped. Without reverted commits, we could get false positives
+# because applying the patch succeeds, but simply results in no
+# changes.
+test_expect_success 'setup of linear history for test involving root' '
+   git checkout b &&
+   revert m b &&
+   git checkout --orphan disjoint &&
+   git rm -rf . &&
+   test_commit x &&
+   test_commit y &&
+   cherry_pick B b
+'
+
+test_run_rebase () {
+   result=$1
+   shift
+   test_expect_$result "rebase $* --onto --root" "
+   reset_rebase &&
+   git rebase $* --onto c --root y &&
+   test_cmp_rev c HEAD~2 &&
+   test_linear_range 'x y' c..
+   "
+}
+test_run_rebase success ''
+test_run_rebase failure -m
+test_run_rebase success -i
+test_run_rebase success -p
+
+test_run_rebase () {
+   result=$1
+   shift
+   test_expect_$result "rebase $* without --onto --root with disjoint 
history" "
+   reset_rebase &&
+   git rebase $* c y &&
+   test_cmp_rev c HEAD~2 &&
+   test_linear_range 'x y' c..
+   "
+}
+test_run_rebase success ''
+test_run_rebase failure -m
+test_run_rebase success -i
+test_run_rebase failure -p
+
+test_run_rebase () {
+   result=$1
+   shift
+   test_expect_$result "rebase $* --onto --root drops patch in onto" "
+   reset_rebase &&
+   git rebase $* --onto m --root B &&
+   test_cmp_rev m HEAD~2 &&
+   test_linear_range 'x y' m..
+   "
+}
+test_run_rebase success ''
+test_run_rebase failure -m
+test_run_rebase success -i
+test_run_rebase success -p
+
+test_run_rebase () {
+   result=$1
+   shift
+   test_expect_$result "rebase $* --onto --root with merge-base does not 
go to root" "
+   reset_rebase &&
+   git rebase $* --onto m --root g &&
+   test_cmp_rev m HEAD~2 &&
+   test_linear_range 'c g' m..
+   "
+}
+
+test_run_rebase success ''
+test_run_rebase success -m
+test_run_rebase success -i
+test_run_rebase failure -p
+
+test_run_rebase () {
+   result=$1
+   shift
+   test_expect_$result "rebase $* without --onto --root with disjoint 
history drops patch in onto" "
+   reset_rebase &&
+   git rebase $* m B &&
+   test_cmp_rev m HEAD~2 &&
+   test_linear_range 'x y' m..
+   "
+}
+test_run_rebase success ''
+test_run_rebase failure -m
+test_run_rebase success -i
+test_run_rebase failure -p
+
+test_run_rebase () {
+   result=$1
+   shift
+   test_expect_$result "rebase $* --root on linear history is a no-op" "
+   reset_rebase &&
+   git rebase $* --root c &&
+   test_cmp_rev c HEAD
+   "
+}
+test_run_rebase failure ''
+test_run_rebase failure -m
+test_run_rebase failure -i
+test_run_rebase failure -p
+
+test_run_rebase () {
+   result=$1
+   shift
+   test_expect_$result "rebase $* -f --root on linear history causes 
re-write" "
+   reset_rebase &&
+   git rebase $* -f --root c &&
+   ! test_cmp_rev a HEAD~2 &&
+   test_linear_range 'a b c' HEAD
+   "
+}
+test_run_rebase success ''
+test_run_rebase success -m
+test_run_rebase success -i
+test_run_rebase success -p
+
 test_done
-- 
1.8.2.674.gd17d3d2

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


[PATCH v3 2/7] add tests for rebasing with patch-equivalence present

2013-05-30 Thread Martin von Zweigbergk
---
 t/lib-rebase.sh   | 17 
 t/t3420-rebase-topology-linear.sh | 85 +++
 2 files changed, 102 insertions(+)

diff --git a/t/lib-rebase.sh b/t/lib-rebase.sh
index 62b3887..16eeb1c 100644
--- a/t/lib-rebase.sh
+++ b/t/lib-rebase.sh
@@ -80,3 +80,20 @@ reset_rebase () {
git reset --hard &&
git clean -f
 }
+
+cherry_pick () {
+   git cherry-pick -n "$2" &&
+   git commit -m "$1" &&
+   git tag "$1"
+}
+
+revert () {
+   git revert -n "$2" &&
+   git commit -m "$1" &&
+   git tag "$1"
+}
+
+make_empty () {
+   git commit --allow-empty -m "$1" &&
+   git tag "$1"
+}
diff --git a/t/t3420-rebase-topology-linear.sh 
b/t/t3420-rebase-topology-linear.sh
index c4b32db..75cc476 100755
--- a/t/t3420-rebase-topology-linear.sh
+++ b/t/t3420-rebase-topology-linear.sh
@@ -75,4 +75,89 @@ test_run_rebase success -m
 test_run_rebase success -i
 test_run_rebase success -p
 
+#   f
+#  /
+# a---b---c---g---h
+#  \
+#   d---G---i
+#
+# uppercase = cherry-picked
+# h = reverted g
+#
+# Reverted patches are there for tests to be able to check if a commit
+# that introduced the same change as another commit is
+# dropped. Without reverted commits, we could get false positives
+# because applying the patch succeeds, but simply results in no
+# changes.
+test_expect_success 'setup of linear history for range selection tests' '
+   git checkout c &&
+   test_commit g &&
+   revert h g &&
+   git checkout d &&
+   cherry_pick G g &&
+   test_commit i &&
+   git checkout b &&
+   test_commit f
+'
+
+test_run_rebase () {
+   result=$1
+   shift
+   test_expect_$result "rebase $* drops patches in upstream" "
+   reset_rebase &&
+   git rebase $* h i &&
+   test_cmp_rev h HEAD~2 &&
+   test_linear_range 'd i' h..
+   "
+}
+test_run_rebase success ''
+test_run_rebase failure -m
+test_run_rebase success -i
+test_run_rebase success -p
+
+test_run_rebase () {
+   result=$1
+   shift
+   test_expect_$result "rebase $* can drop last patch if in upstream" "
+   reset_rebase &&
+   git rebase $* h G &&
+   test_cmp_rev h HEAD^ &&
+   test_linear_range 'd' h..
+   "
+}
+test_run_rebase success ''
+test_run_rebase failure -m
+test_run_rebase success -i
+test_run_rebase success -p
+
+test_run_rebase () {
+   result=$1
+   shift
+   test_expect_$result "rebase $* --onto drops patches in upstream" "
+   reset_rebase &&
+   git rebase $* --onto f h i &&
+   test_cmp_rev f HEAD~2 &&
+   test_linear_range 'd i' f..
+   "
+}
+test_run_rebase success ''
+test_run_rebase failure -m
+test_run_rebase success -i
+test_run_rebase success -p
+
+test_run_rebase () {
+   result=$1
+   shift
+   test_expect_$result "rebase $* --onto does not drop patches in onto" "
+   reset_rebase &&
+   git rebase $* --onto h f i &&
+   test_cmp_rev h HEAD~3 &&
+   test_linear_range 'd G i' h..
+   "
+}
+test_run_rebase success ''
+test_run_rebase success -m
+test_run_rebase success -i
+test_run_rebase success -p
+
 test_done
-- 
1.8.2.674.gd17d3d2

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


[PATCH v3 0/7] Rebase topology test

2013-05-30 Thread Martin von Zweigbergk
Patches are now expected to be dropped iff they are on upstream. I've
also followed all of Johannes's other suggestions except for the one
about topo-order.

Martin von Zweigbergk (7):
  add simple tests of consistency across rebase types
  add tests for rebasing with patch-equivalence present
  add tests for rebasing of empty commits
  add tests for rebasing root
  add tests for rebasing merged history
  t3406: modernize style
  tests: move test for rebase messages from t3400 to t3406

 t/lib-rebase.sh   |  32 
 t/t3400-rebase.sh |  53 +-
 t/t3401-rebase-partial.sh |  69 
 t/t3404-rebase-interactive.sh |  10 +-
 t/t3406-rebase-message.sh |  50 +++---
 t/t3409-rebase-preserve-merges.sh |  53 --
 t/t3420-rebase-topology-linear.sh | 350 ++
 t/t3425-rebase-topology-merges.sh | 252 +++
 8 files changed, 666 insertions(+), 203 deletions(-)
 delete mode 100755 t/t3401-rebase-partial.sh
 create mode 100755 t/t3420-rebase-topology-linear.sh
 create mode 100755 t/t3425-rebase-topology-merges.sh

-- 
1.8.2.674.gd17d3d2

--
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 1/7] add simple tests of consistency across rebase types

2013-05-30 Thread Martin von Zweigbergk
Helped-by: Johannes Sixt 
---
 t/lib-rebase.sh   | 15 
 t/t3420-rebase-topology-linear.sh | 78 +++
 2 files changed, 93 insertions(+)
 create mode 100755 t/t3420-rebase-topology-linear.sh

diff --git a/t/lib-rebase.sh b/t/lib-rebase.sh
index 6ccf797..62b3887 100644
--- a/t/lib-rebase.sh
+++ b/t/lib-rebase.sh
@@ -65,3 +65,18 @@ EOF
test_set_editor "$(pwd)/fake-editor.sh"
chmod a+x fake-editor.sh
 }
+
+# checks that the revisions in "$2" represent a linear range with the
+# subjects in "$1"
+test_linear_range () {
+   ! { git log --format=%p "$2" | sane_grep " " ;} &&
+   expected=$1
+   set -- $(git log --reverse --format=%s "$2")
+   test "$expected" = "$*"
+}
+
+reset_rebase () {
+   git rebase --abort # may fail; ignore exit code
+   git reset --hard &&
+   git clean -f
+}
diff --git a/t/t3420-rebase-topology-linear.sh 
b/t/t3420-rebase-topology-linear.sh
new file mode 100755
index 000..c4b32db
--- /dev/null
+++ b/t/t3420-rebase-topology-linear.sh
@@ -0,0 +1,78 @@
+#!/bin/sh
+
+test_description='basic rebase topology tests'
+. ./test-lib.sh
+. "$TEST_DIRECTORY"/lib-rebase.sh
+
+# a---b---c
+#  \
+#   d---e
+test_expect_success 'setup' '
+   test_commit a &&
+   test_commit b &&
+   test_commit c &&
+   git checkout b &&
+   test_commit d &&
+   test_commit e
+'
+
+test_run_rebase () {
+   result=$1
+   shift
+   test_expect_$result "simple rebase $*" "
+   reset_rebase &&
+   git rebase $* c e &&
+   test_cmp_rev c HEAD~2 &&
+   test_linear_range 'd e' c..
+   "
+}
+test_run_rebase success ''
+test_run_rebase success -m
+test_run_rebase success -i
+test_run_rebase success -p
+
+test_run_rebase () {
+   result=$1
+   shift
+   test_expect_$result "rebase $* is no-op if upstream is an ancestor" "
+   reset_rebase &&
+   git rebase $* b e &&
+   test_cmp_rev e HEAD
+   "
+}
+test_run_rebase success ''
+test_run_rebase success -m
+test_run_rebase success -i
+test_run_rebase success -p
+
+test_run_rebase () {
+   result=$1
+   shift
+   test_expect_$result "rebase $* -f rewrites even if upstream is an 
ancestor" "
+   reset_rebase &&
+   git rebase $* -f b e &&
+   ! test_cmp_rev e HEAD &&
+   test_cmp_rev b HEAD~2 &&
+   test_linear_range 'd e' b..
+   "
+}
+test_run_rebase success ''
+test_run_rebase success -m
+test_run_rebase success -i
+test_run_rebase failure -p
+
+test_run_rebase () {
+   result=$1
+   shift
+   test_expect_$result "rebase $* fast-forwards if an ancestor of 
upstream" "
+   reset_rebase &&
+   git rebase $* e b &&
+   test_cmp_rev e HEAD
+   "
+}
+test_run_rebase success ''
+test_run_rebase success -m
+test_run_rebase success -i
+test_run_rebase success -p
+
+test_done
-- 
1.8.2.674.gd17d3d2

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


[PATCH v3 3/7] add tests for rebasing of empty commits

2013-05-30 Thread Martin von Zweigbergk
---
 t/t3401-rebase-partial.sh | 24 
 t/t3420-rebase-topology-linear.sh | 58 +++
 2 files changed, 58 insertions(+), 24 deletions(-)

diff --git a/t/t3401-rebase-partial.sh b/t/t3401-rebase-partial.sh
index 58f4823..7ba1797 100755
--- a/t/t3401-rebase-partial.sh
+++ b/t/t3401-rebase-partial.sh
@@ -42,28 +42,4 @@ test_expect_success 'rebase --merge topic branch that was 
partially merged upstr
test_path_is_missing .git/rebase-merge
 '
 
-test_expect_success 'rebase ignores empty commit' '
-   git reset --hard A &&
-   git commit --allow-empty -m empty &&
-   test_commit D &&
-   git rebase C &&
-   test "$(git log --format=%s C..)" = "D"
-'
-
-test_expect_success 'rebase --keep-empty' '
-   git reset --hard D &&
-   git rebase --keep-empty C &&
-   test "$(git log --format=%s C..)" = "D
-empty"
-'
-
-test_expect_success 'rebase --keep-empty keeps empty even if already in 
upstream' '
-   git reset --hard A &&
-   git commit --allow-empty -m also-empty &&
-   git rebase --keep-empty D &&
-   test "$(git log --format=%s A..)" = "also-empty
-D
-empty"
-'
-
 test_done
diff --git a/t/t3420-rebase-topology-linear.sh 
b/t/t3420-rebase-topology-linear.sh
index 75cc476..81e3d59 100755
--- a/t/t3420-rebase-topology-linear.sh
+++ b/t/t3420-rebase-topology-linear.sh
@@ -160,4 +160,62 @@ test_run_rebase success -m
 test_run_rebase success -i
 test_run_rebase success -p
 
+# a---b---c---j!
+#  \
+#   d---k!--l
+#
+# ! = empty
+test_expect_success 'setup of linear history for empty commit tests' '
+   git checkout c &&
+   make_empty j &&
+   git checkout d &&
+   make_empty k &&
+   test_commit l
+'
+
+test_run_rebase () {
+   result=$1
+   shift
+   test_expect_$result "rebase $* drops empty commit" "
+   reset_rebase &&
+   git rebase $* c l &&
+   test_cmp_rev c HEAD~2 &&
+   test_linear_range 'd l' c..
+   "
+}
+test_run_rebase success ''
+test_run_rebase success -m
+test_run_rebase success -i
+test_run_rebase success -p
+
+test_run_rebase () {
+   result=$1
+   shift
+   test_expect_$result "rebase $* --keep-empty" "
+   reset_rebase &&
+   git rebase $* --keep-empty c l &&
+   test_cmp_rev c HEAD~3 &&
+   test_linear_range 'd k l' c..
+   "
+}
+test_run_rebase success ''
+test_run_rebase failure -m
+test_run_rebase success -i
+test_run_rebase failure -p
+
+test_run_rebase () {
+   result=$1
+   shift
+   test_expect_$result "rebase $* --keep-empty keeps empty even if already 
in upstream" "
+   reset_rebase &&
+   git rebase $* --keep-empty j l &&
+   test_cmp_rev j HEAD~3 &&
+   test_linear_range 'd k l' j..
+   "
+}
+test_run_rebase success ''
+test_run_rebase failure -m
+test_run_rebase failure -i
+test_run_rebase failure -p
+
 test_done
-- 
1.8.2.674.gd17d3d2

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


Re: [PATCH v2 5/7] add tests for rebasing merged history

2013-05-30 Thread Martin von Zweigbergk
On Wed, May 29, 2013 at 12:57 AM, Johannes Sixt  wrote:
> Am 5/29/2013 8:39, schrieb Martin von Zweigbergk:
>> +# a---b---c
>> +#  \   \
>> +#   d---e   \
>> +#\   \   \
>> +# n---o---w---v
>> +#  \
>> +#   z
>
>> +#TODO: make all flavors of rebase use --topo-order
>> +test_run_rebase success 'e n o' ''
>> +test_run_rebase success 'e n o' -m
>> +test_run_rebase success 'n o e' -i
>
> As test_commit offers predictable timestamps, I think you can work around
> this discrepancy by generating commits n and o before e. (That is not a
> solution--just a workaround that depends on the current
> implementation--because the order in which parents of a merge are listed
> is unspecified.)

I actually liked it as documentation of the current inconsistency and
with an explicit TODO.

I have addressed the remainder of your comments in this and the next
message. Thanks again.
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2 2/7] add tests for rebasing with patch-equivalence present

2013-05-30 Thread Martin von Zweigbergk
On Thu, May 30, 2013 at 5:54 AM, Johannes Sixt  wrote:
> Am 30.05.2013 07:30, schrieb Martin von Zweigbergk:
>> On Wed, May 29, 2013 at 12:09 AM, Johannes Sixt  wrote:
>>> Am 5/29/2013 8:39, schrieb Martin von Zweigbergk:
>>>> +#   f
>>>> +#  /
>>>> +# a---b---c---g---h
>>>> +#  \
>>>> +#   d---G---i
>>> ...
>>>> +test_run_rebase () {
>>>> + result=$1
>>>> + shift
>>>> + test_expect_$result "rebase $* --onto drops patches in onto" "
>>>> + reset_rebase &&
>>>> + git rebase $* --onto h f i &&
>>>> + test_cmp_rev h HEAD~2 &&
>>>> + test_linear_range 'd i' h..
>>>
>>> Isn't this expectation wrong? The upstream of the rebased branch is f, and
>>> it does not contain G. Hence, G should be replayed. Since h is the
>>> reversal of g, the state at h is the same as at c, and applying G should
>>> succeed (it is the same change as g). Therefore, I think the correct
>>> expectation is:
>>>
>>> test_linear_range 'd G i' h..
>>
>> Good question! It is really not obvious what the right answer is. Some
>> arguments in favor of dropping 'G':
>>
>> 1. Let's say origin/master points to 'b' when you start the 'd G i'
>> branch. You then send the 'G' patch to Junio who applies it as 'g'
>> (cherry-picking direction is reversed compared to figure, but same
>> effect). You then "git pull --rebase" when master on origin points to
>> 'h'. Because of the cleverness in 'git pull --rebase', it issues 'git
>> rebase --onto h b i'.
>
> The reason for this git pull cleverness is to be prepared for rewritten
> history:
>
>b'--c'--g'--h'
>   /
>  a---b
>   \
>d---G---i
>
> to avoid that b is rebased.

Right. It doesn't currently drop 'G' and maybe it shouldn't, so let's
leave it as is for now, I would say.

>> 2. In the test a little before the above one, we instead do 'git
>> rebase --onto f h i' and make sure that the 'G' is _not_ lost. In that
>> case it doesn't matter what's in $branch..$upstream. Do we agree that
>> $branch..$upstream should never matter (instead, $upstream is only
>> used to find merge base with $branch)?
>
> No, we do not agree. $branch..$upstream should be the set of patches
> that should be omitted. $branch..$onto should not matter. $onto is only
> used to specify the destination of the rebased commits.

Ok. As I said to Felipe, I'm not sure why I was so convinced that it's
bad to lose the patch in 'git rebase --onto f h i'. It can result in
lost work, but it seems rare enough that no one has reported it,
AFAIK.

I'll change those tests in a re-roll, and perhaps I'll drop a few of
them. Let me know if you (anyone) disagree.


Martin

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


Re: [PATCH v2 2/7] add tests for rebasing with patch-equivalence present

2013-05-29 Thread Martin von Zweigbergk
On Wed, May 29, 2013 at 11:40 PM, Felipe Contreras
 wrote:
> On Thu, May 30, 2013 at 1:14 AM, Martin von Zweigbergk
>  wrote:
>> On Wed, May 29, 2013 at 10:41 PM, Felipe Contreras
>>  wrote:
>>> On Thu, May 30, 2013 at 12:30 AM, Martin von Zweigbergk
>>>  wrote:
>>>> On Wed, May 29, 2013 at 12:09 AM, Johannes Sixt  
>>>> wrote:
>>>>> Am 5/29/2013 8:39, schrieb Martin von Zweigbergk:
>>>>>> +#   f
>>>>>> +#  /
>>>>>> +# a---b---c---g---h
>>>>>> +#  \
>>>>>> +#   d---G---i
>>>>> ...
>>>>>> +test_run_rebase () {
>>>>>> + result=$1
>>>>>> + shift
>>>>>> + test_expect_$result "rebase $* --onto drops patches in onto" "
>>>>>> + reset_rebase &&
>>>>>> + git rebase $* --onto h f i &&
>>>>>> + test_cmp_rev h HEAD~2 &&
>>>>>> + test_linear_range 'd i' h..
>>>>>
>>>>> Isn't this expectation wrong? The upstream of the rebased branch is f, and
>>>>> it does not contain G. Hence, G should be replayed. Since h is the
>>>>> reversal of g, the state at h is the same as at c, and applying G should
>>>>> succeed (it is the same change as g). Therefore, I think the correct
>>>>> expectation is:
>>>>>
>>>>> test_linear_range 'd G i' h..
>>>>
>>>> Good question! It is really not obvious what the right answer is. Some
>>>> arguments in favor of dropping 'G':
>>>
>>> I think the answer is obvious; G should not be dropped. Maybe it made
>>> sense to drop g in upstream, but d fixes an issue, and it makes sense
>>> to apply G on upstream.
>>
>> Well, maybe I was wrong in thinking that dropping 'G' in 'git rebase
>> --onto f h i' is bad. It seems to complicate things a lot, so maybe we
>> should just decide that it's fine to do that (to drop 'G' in that
>> case). Since that's mostly how it has worked forever and no one seems
>> to have reported a problem with it, I'm probably just being paranoid.
>> Thoughts?
>
> Huh? I said the opposite; G should *not* be dropped.

I suspect you missed that I said 'git rebase --onto f h i', not 'git
rebase --onto h f i'. Sorry, I should have pointed that out.
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2 2/7] add tests for rebasing with patch-equivalence present

2013-05-29 Thread Martin von Zweigbergk
On Wed, May 29, 2013 at 10:41 PM, Felipe Contreras
 wrote:
> On Thu, May 30, 2013 at 12:30 AM, Martin von Zweigbergk
>  wrote:
>> On Wed, May 29, 2013 at 12:09 AM, Johannes Sixt  wrote:
>>> Am 5/29/2013 8:39, schrieb Martin von Zweigbergk:
>>>> +#   f
>>>> +#  /
>>>> +# a---b---c---g---h
>>>> +#  \
>>>> +#   d---G---i
>>> ...
>>>> +test_run_rebase () {
>>>> + result=$1
>>>> + shift
>>>> + test_expect_$result "rebase $* --onto drops patches in onto" "
>>>> + reset_rebase &&
>>>> + git rebase $* --onto h f i &&
>>>> + test_cmp_rev h HEAD~2 &&
>>>> + test_linear_range 'd i' h..
>>>
>>> Isn't this expectation wrong? The upstream of the rebased branch is f, and
>>> it does not contain G. Hence, G should be replayed. Since h is the
>>> reversal of g, the state at h is the same as at c, and applying G should
>>> succeed (it is the same change as g). Therefore, I think the correct
>>> expectation is:
>>>
>>> test_linear_range 'd G i' h..
>>
>> Good question! It is really not obvious what the right answer is. Some
>> arguments in favor of dropping 'G':
>
> I think the answer is obvious; G should not be dropped. Maybe it made
> sense to drop g in upstream, but d fixes an issue, and it makes sense
> to apply G on upstream.

Well, maybe I was wrong in thinking that dropping 'G' in 'git rebase
--onto f h i' is bad. It seems to complicate things a lot, so maybe we
should just decide that it's fine to do that (to drop 'G' in that
case). Since that's mostly how it has worked forever and no one seems
to have reported a problem with it, I'm probably just being paranoid.
Thoughts?
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2 4/7] add tests for rebasing root

2013-05-29 Thread Martin von Zweigbergk
On Wed, May 29, 2013 at 12:31 AM, Johannes Sixt  wrote:
> Am 5/29/2013 8:39, schrieb Martin von Zweigbergk:
>> +test_run_rebase () {
>> + result=$1
>> + shift
>> + test_expect_$result "rebase $* --onto --root with merge-base does not 
>> go to root" "
>> + reset_rebase &&
>> + git rebase $* --onto m --root g &&
>> + test_cmp_rev m HEAD~2 &&
>> + test_linear_range 'c g' m..
>
> Here you check the outcome. There is no explicit check whether the rebase
> attempted to replay a and b. But that check is implicit: If a or b were
> attempted to replay, the rebase would have been interrupted with "no new
> changes". Right?

Because 'm' is a reverted 'b', I think if it had gone to the root, we
would have seen 'b m c g' (I _think_ 'a' would be silently skipped at
least in am mode).

>> +test_run_rebase failure -p
>
> Just curious: Does the last one fail because the result is not correct or
> because it does go to the root?

Because the result is not correct; it first checks out 'm', but
something goes wrong (maybe because 'm' gets written to
/rewritten/root?) and it somehow fast-forwards to 'c' (from 'b'?).
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2 2/7] add tests for rebasing with patch-equivalence present

2013-05-29 Thread Martin von Zweigbergk
On Wed, May 29, 2013 at 12:09 AM, Johannes Sixt  wrote:
> Am 5/29/2013 8:39, schrieb Martin von Zweigbergk:
>> +#   f
>> +#  /
>> +# a---b---c---g---h
>> +#  \
>> +#   d---G---i
> ...
>> +test_run_rebase () {
>> + result=$1
>> + shift
>> + test_expect_$result "rebase $* --onto drops patches in onto" "
>> + reset_rebase &&
>> + git rebase $* --onto h f i &&
>> + test_cmp_rev h HEAD~2 &&
>> + test_linear_range 'd i' h..
>
> Isn't this expectation wrong? The upstream of the rebased branch is f, and
> it does not contain G. Hence, G should be replayed. Since h is the
> reversal of g, the state at h is the same as at c, and applying G should
> succeed (it is the same change as g). Therefore, I think the correct
> expectation is:
>
> test_linear_range 'd G i' h..

Good question! It is really not obvious what the right answer is. Some
arguments in favor of dropping 'G':

1. Let's say origin/master points to 'b' when you start the 'd G i'
branch. You then send the 'G' patch to Junio who applies it as 'g'
(cherry-picking direction is reversed compared to figure, but same
effect). You then "git pull --rebase" when master on origin points to
'h'. Because of the cleverness in 'git pull --rebase', it issues 'git
rebase --onto h b i'. In this case it's clearly useful to have the
patch dropped.

2. In the test a little before the above one, we instead do 'git
rebase --onto f h i' and make sure that the 'G' is _not_ lost. In that
case it doesn't matter what's in $branch..$upstream. Do we agree that
$branch..$upstream should never matter (instead, $upstream is only
used to find merge base with $branch)? Do we also agree that 'git
rebase a b' should be identical to 'git rebase --onto a a b'? Because
'git rebase h i' should clearly drop 'G', then so should 'git rebase
--onto h h i'. Then, if we agreed that $branch..$upstream doesn't
matter, 'git rebase --onto h f i' should behave the same, no?


The set of commits to rebase that I was thinking of using was
"$upstream..$branch, unless equivalent with patch in $branch..$onto".
But I'm not very confident about my conclusions above :-)


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


[PATCH v2 0/7] Rebase topology test

2013-05-28 Thread Martin von Zweigbergk
After way too long, here is finally a new version of the tests I sent
at: http://thread.gmane.org/gmane.comp.version-control.git/205796.

I have split the test up into two files. They stil take quite some
time to run.

Martin von Zweigbergk (7):
  add simple tests of consistency across rebase types
  add tests for rebasing with patch-equivalence present
  add tests for rebasing of empty commits
  add tests for rebasing root
  add tests for rebasing merged history
  t3406: modernize style
  tests: move test for rebase messages from t3400 to t3406

 t/lib-rebase.sh   |  32 
 t/t3400-rebase.sh |  53 +-
 t/t3401-rebase-partial.sh |  69 
 t/t3404-rebase-interactive.sh |  10 +-
 t/t3406-rebase-message.sh |  50 +++---
 t/t3409-rebase-preserve-merges.sh |  53 --
 t/t3420-rebase-topology-linear.sh | 350 ++
 t/t3425-rebase-topology-merges.sh | 250 +++
 8 files changed, 664 insertions(+), 203 deletions(-)
 delete mode 100755 t/t3401-rebase-partial.sh
 create mode 100755 t/t3420-rebase-topology-linear.sh
 create mode 100755 t/t3425-rebase-topology-merges.sh

-- 
1.8.2.674.gd17d3d2

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


[PATCH v2 2/7] add tests for rebasing with patch-equivalence present

2013-05-28 Thread Martin von Zweigbergk
---
 t/lib-rebase.sh   | 17 
 t/t3420-rebase-topology-linear.sh | 85 +++
 2 files changed, 102 insertions(+)

diff --git a/t/lib-rebase.sh b/t/lib-rebase.sh
index 62b3887..16eeb1c 100644
--- a/t/lib-rebase.sh
+++ b/t/lib-rebase.sh
@@ -80,3 +80,20 @@ reset_rebase () {
git reset --hard &&
git clean -f
 }
+
+cherry_pick () {
+   git cherry-pick -n "$2" &&
+   git commit -m "$1" &&
+   git tag "$1"
+}
+
+revert () {
+   git revert -n "$2" &&
+   git commit -m "$1" &&
+   git tag "$1"
+}
+
+make_empty () {
+   git commit --allow-empty -m "$1" &&
+   git tag "$1"
+}
diff --git a/t/t3420-rebase-topology-linear.sh 
b/t/t3420-rebase-topology-linear.sh
index c4b32db..1152491 100755
--- a/t/t3420-rebase-topology-linear.sh
+++ b/t/t3420-rebase-topology-linear.sh
@@ -75,4 +75,89 @@ test_run_rebase success -m
 test_run_rebase success -i
 test_run_rebase success -p
 
+#   f
+#  /
+# a---b---c---g---h
+#  \
+#   d---G---i
+#
+# uppercase = cherry-picked
+# h = reverted g
+#
+# Reverted patches are there for tests to be able to check if a commit
+# that introduced the same change as another commit is
+# dropped. Without reverted commits, we could get false positives
+# because applying the patch succeeds, but simply results in no
+# changes.
+test_expect_success 'setup of linear history for range selection tests' '
+   git checkout c &&
+   test_commit g &&
+   revert h g &&
+   git checkout d &&
+   cherry_pick G g &&
+   test_commit i &&
+   git checkout b &&
+   test_commit f
+'
+
+test_run_rebase () {
+   result=$1
+   shift
+   test_expect_$result "rebase $* drops patches in upstream" "
+   reset_rebase &&
+   git rebase $* h i &&
+   test_cmp_rev h HEAD~2 &&
+   test_linear_range 'd i' h..
+   "
+}
+test_run_rebase success ''
+test_run_rebase failure -m
+test_run_rebase success -i
+test_run_rebase success -p
+
+test_run_rebase () {
+   result=$1
+   shift
+   test_expect_$result "rebase $* can drop last patch if in upstream" "
+   reset_rebase &&
+   git rebase $* h G &&
+   test_cmp_rev h HEAD^ &&
+   test_linear_range 'd' h..
+   "
+}
+test_run_rebase success ''
+test_run_rebase failure -m
+test_run_rebase success -i
+test_run_rebase success -p
+
+test_run_rebase () {
+   result=$1
+   shift
+   test_expect_$result "rebase $* --onto does not lose patches in 
upstream" "
+   reset_rebase &&
+   git rebase $* --onto f h i &&
+   test_cmp_rev f HEAD~3 &&
+   test_linear_range 'd G i' f..
+   "
+}
+test_run_rebase failure ''
+test_run_rebase success -m
+test_run_rebase failure -i
+test_run_rebase failure -p
+
+test_run_rebase () {
+   result=$1
+   shift
+   test_expect_$result "rebase $* --onto drops patches in onto" "
+   reset_rebase &&
+   git rebase $* --onto h f i &&
+   test_cmp_rev h HEAD~2 &&
+   test_linear_range 'd i' h..
+   "
+}
+test_run_rebase failure ''
+test_run_rebase failure -m
+test_run_rebase failure -i
+test_run_rebase failure -p
+
 test_done
-- 
1.8.2.674.gd17d3d2

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


[PATCH v2 7/7] tests: move test for rebase messages from t3400 to t3406

2013-05-28 Thread Martin von Zweigbergk
t3406 is supposed to test "messages from rebase operation", so let's
move tests in t3400 that fit that description into 3406. Most of the
functionality they tested, except for the messages, has now been
subsumed by t3420.
---
 t/t3400-rebase.sh | 22 --
 t/t3406-rebase-message.sh | 22 ++
 2 files changed, 22 insertions(+), 22 deletions(-)

diff --git a/t/t3400-rebase.sh b/t/t3400-rebase.sh
index b436ef4..45a55e9 100755
--- a/t/t3400-rebase.sh
+++ b/t/t3400-rebase.sh
@@ -59,28 +59,6 @@ test_expect_success 'rebase against master' '
git rebase master
 '
 
-test_expect_success 'rebase against master twice' '
-   git rebase master >out &&
-   test_i18ngrep "Current branch my-topic-branch is up to date" out
-'
-
-test_expect_success 'rebase against master twice with --force' '
-   git rebase --force-rebase master >out &&
-   test_i18ngrep "Current branch my-topic-branch is up to date, rebase 
forced" out
-'
-
-test_expect_success 'rebase against master twice from another branch' '
-   git checkout my-topic-branch^ &&
-   git rebase master my-topic-branch >out &&
-   test_i18ngrep "Current branch my-topic-branch is up to date" out
-'
-
-test_expect_success 'rebase fast-forward to master' '
-   git checkout my-topic-branch^ &&
-   git rebase my-topic-branch >out &&
-   test_i18ngrep "Fast-forwarded HEAD to my-topic-branch" out
-'
-
 test_expect_success 'the rebase operation should not have destroyed author 
information' '
! (git log | grep "Author:" | grep "<>")
 '
diff --git a/t/t3406-rebase-message.sh b/t/t3406-rebase-message.sh
index fe8c27f..0392e36 100755
--- a/t/t3406-rebase-message.sh
+++ b/t/t3406-rebase-message.sh
@@ -30,6 +30,28 @@ test_expect_success 'rebase -m' '
test_cmp expect actual
 '
 
+test_expect_success 'rebase against master twice' '
+   git rebase master >out &&
+   test_i18ngrep "Current branch topic is up to date" out
+'
+
+test_expect_success 'rebase against master twice with --force' '
+   git rebase --force-rebase master >out &&
+   test_i18ngrep "Current branch topic is up to date, rebase forced" out
+'
+
+test_expect_success 'rebase against master twice from another branch' '
+   git checkout topic^ &&
+   git rebase master topic >out &&
+   test_i18ngrep "Current branch topic is up to date" out
+'
+
+test_expect_success 'rebase fast-forward to master' '
+   git checkout topic^ &&
+   git rebase topic >out &&
+   test_i18ngrep "Fast-forwarded HEAD to topic" out
+'
+
 test_expect_success 'rebase --stat' '
git reset --hard start &&
 git rebase --stat master >diffstat.txt &&
-- 
1.8.2.674.gd17d3d2

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


[PATCH v2 5/7] add tests for rebasing merged history

2013-05-28 Thread Martin von Zweigbergk
---
 t/t3400-rebase.sh |  31 +
 t/t3401-rebase-partial.sh |  45 ---
 t/t3404-rebase-interactive.sh |  10 +-
 t/t3409-rebase-preserve-merges.sh |  53 
 t/t3425-rebase-topology-merges.sh | 250 ++
 5 files changed, 252 insertions(+), 137 deletions(-)
 delete mode 100755 t/t3401-rebase-partial.sh
 create mode 100755 t/t3425-rebase-topology-merges.sh

diff --git a/t/t3400-rebase.sh b/t/t3400-rebase.sh
index b58fa1a..b436ef4 100755
--- a/t/t3400-rebase.sh
+++ b/t/t3400-rebase.sh
@@ -40,13 +40,6 @@ test_expect_success 'prepare repository with topic branches' 
'
echo Side >>C &&
git add C &&
git commit -m "Add C" &&
-   git checkout -b nonlinear my-topic-branch &&
-   echo Edit >>B &&
-   git add B &&
-   git commit -m "Modify B" &&
-   git merge side &&
-   git checkout -b upstream-merged-nonlinear &&
-   git merge master &&
git checkout -f my-topic-branch &&
git tag topic
 '
@@ -106,31 +99,9 @@ test_expect_success 'rebase from ambiguous branch name' '
git rebase master
 '
 
-test_expect_success 'rebase after merge master' '
-   git checkout --detach refs/tags/topic &&
-   git branch -D topic &&
-   git reset --hard topic &&
-   git merge master &&
-   git rebase master &&
-   ! (git show | grep "^Merge:")
-'
-
-test_expect_success 'rebase of history with merges is linearized' '
-   git checkout nonlinear &&
-   test 4 = $(git rev-list master.. | wc -l) &&
-   git rebase master &&
-   test 3 = $(git rev-list master.. | wc -l)
-'
-
-test_expect_success 'rebase of history with merges after upstream merge is 
linearized' '
-   git checkout upstream-merged-nonlinear &&
-   test 5 = $(git rev-list master.. | wc -l) &&
-   git rebase master &&
-   test 3 = $(git rev-list master.. | wc -l)
-'
-
 test_expect_success 'rebase a single mode change' '
git checkout master &&
+   git branch -D topic &&
echo 1 >X &&
git add X &&
test_tick &&
diff --git a/t/t3401-rebase-partial.sh b/t/t3401-rebase-partial.sh
deleted file mode 100755
index 7ba1797..000
--- a/t/t3401-rebase-partial.sh
+++ /dev/null
@@ -1,45 +0,0 @@
-#!/bin/sh
-#
-# Copyright (c) 2006 Yann Dirson, based on t3400 by Amos Waterland
-#
-
-test_description='git rebase should detect patches integrated upstream
-
-This test cherry-picks one local change of two into master branch, and
-checks that git rebase succeeds with only the second patch in the
-local branch.
-'
-. ./test-lib.sh
-
-test_expect_success 'prepare repository with topic branch' '
-   test_commit A &&
-   git checkout -b my-topic-branch &&
-   test_commit B &&
-   test_commit C &&
-   git checkout -f master &&
-   test_commit A2 A.t
-'
-
-test_expect_success 'pick top patch from topic branch into master' '
-   git cherry-pick C &&
-   git checkout -f my-topic-branch
-'
-
-test_debug '
-   git cherry master &&
-   git format-patch -k --stdout --full-index master >/dev/null &&
-   gitk --all & sleep 1
-'
-
-test_expect_success 'rebase topic branch against new master and check git am 
did not get halted' '
-   git rebase master &&
-   test_path_is_missing .git/rebase-apply
-'
-
-test_expect_success 'rebase --merge topic branch that was partially merged 
upstream' '
-   git reset --hard C &&
-   git rebase --merge master &&
-   test_path_is_missing .git/rebase-merge
-'
-
-test_done
diff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh
index a58406d..ffcaf02 100755
--- a/t/t3404-rebase-interactive.sh
+++ b/t/t3404-rebase-interactive.sh
@@ -477,19 +477,11 @@ test_expect_success 'interrupted squash works as expected 
(case 2)' '
test $one = $(git rev-parse HEAD~2)
 '
 
-test_expect_success 'ignore patch if in upstream' '
-   HEAD=$(git rev-parse HEAD) &&
-   git checkout -b has-cherry-picked HEAD^ &&
+test_expect_success '--continue tries to commit, even for "edit"' '
echo unrelated > file7 &&
git add file7 &&
test_tick &&
git commit -m "unrelated change" &&
-   git cherry-pick $HEAD &&
-   EXPECT_COUNT=1 git rebase -i $HEAD &&
-   test $HEAD = $(git rev-parse HEAD^)
-'
-
-test_expect_success '--continue tries to commit, even for "edit"' '
parent=$(git rev-parse HEAD^) &&
test_tick &&
FAKE_LINES="edit 1" git rebase -i HEAD^ &&
diff --git a/t/t3409-rebase-preserve-merges.sh 
b/t/t3409-rebase-preserve-merges.sh
index 6de4e22..2e0c364 100755
--- a/t/t3409-rebase-preserve-merges.sh
+++ b/t/t3409-rebase-preserve-merges.sh
@@ -11,14 +11,6 @@ Run "git rebase -p" and check that merges are properly 
carried along
 GIT_AUTHOR_EMAIL=bogus_email_address
 export GIT_AUTHOR_EMAIL
 
-# Clone 1 (trivial merge):
-#
-# A1--A2  <-- origin/master
-#  \   \
-#   B1--M  <-- topic
-#\
-# B2  <-- origin/topic
-#
 #

[PATCH v2 1/7] add simple tests of consistency across rebase types

2013-05-28 Thread Martin von Zweigbergk
Helped-by: Johannes Sixt 
---
 t/lib-rebase.sh   | 15 
 t/t3420-rebase-topology-linear.sh | 78 +++
 2 files changed, 93 insertions(+)
 create mode 100755 t/t3420-rebase-topology-linear.sh

diff --git a/t/lib-rebase.sh b/t/lib-rebase.sh
index 6ccf797..62b3887 100644
--- a/t/lib-rebase.sh
+++ b/t/lib-rebase.sh
@@ -65,3 +65,18 @@ EOF
test_set_editor "$(pwd)/fake-editor.sh"
chmod a+x fake-editor.sh
 }
+
+# checks that the revisions in "$2" represent a linear range with the
+# subjects in "$1"
+test_linear_range () {
+   ! { git log --format=%p "$2" | sane_grep " " ;} &&
+   expected=$1
+   set -- $(git log --reverse --format=%s "$2")
+   test "$expected" = "$*"
+}
+
+reset_rebase () {
+   git rebase --abort # may fail; ignore exit code
+   git reset --hard &&
+   git clean -f
+}
diff --git a/t/t3420-rebase-topology-linear.sh 
b/t/t3420-rebase-topology-linear.sh
new file mode 100755
index 000..c4b32db
--- /dev/null
+++ b/t/t3420-rebase-topology-linear.sh
@@ -0,0 +1,78 @@
+#!/bin/sh
+
+test_description='basic rebase topology tests'
+. ./test-lib.sh
+. "$TEST_DIRECTORY"/lib-rebase.sh
+
+# a---b---c
+#  \
+#   d---e
+test_expect_success 'setup' '
+   test_commit a &&
+   test_commit b &&
+   test_commit c &&
+   git checkout b &&
+   test_commit d &&
+   test_commit e
+'
+
+test_run_rebase () {
+   result=$1
+   shift
+   test_expect_$result "simple rebase $*" "
+   reset_rebase &&
+   git rebase $* c e &&
+   test_cmp_rev c HEAD~2 &&
+   test_linear_range 'd e' c..
+   "
+}
+test_run_rebase success ''
+test_run_rebase success -m
+test_run_rebase success -i
+test_run_rebase success -p
+
+test_run_rebase () {
+   result=$1
+   shift
+   test_expect_$result "rebase $* is no-op if upstream is an ancestor" "
+   reset_rebase &&
+   git rebase $* b e &&
+   test_cmp_rev e HEAD
+   "
+}
+test_run_rebase success ''
+test_run_rebase success -m
+test_run_rebase success -i
+test_run_rebase success -p
+
+test_run_rebase () {
+   result=$1
+   shift
+   test_expect_$result "rebase $* -f rewrites even if upstream is an 
ancestor" "
+   reset_rebase &&
+   git rebase $* -f b e &&
+   ! test_cmp_rev e HEAD &&
+   test_cmp_rev b HEAD~2 &&
+   test_linear_range 'd e' b..
+   "
+}
+test_run_rebase success ''
+test_run_rebase success -m
+test_run_rebase success -i
+test_run_rebase failure -p
+
+test_run_rebase () {
+   result=$1
+   shift
+   test_expect_$result "rebase $* fast-forwards if an ancestor of 
upstream" "
+   reset_rebase &&
+   git rebase $* e b &&
+   test_cmp_rev e HEAD
+   "
+}
+test_run_rebase success ''
+test_run_rebase success -m
+test_run_rebase success -i
+test_run_rebase success -p
+
+test_done
-- 
1.8.2.674.gd17d3d2

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


[PATCH v2 4/7] add tests for rebasing root

2013-05-28 Thread Martin von Zweigbergk
---
 t/t3420-rebase-topology-linear.sh | 129 ++
 1 file changed, 129 insertions(+)

diff --git a/t/t3420-rebase-topology-linear.sh 
b/t/t3420-rebase-topology-linear.sh
index 40fe264..2429aa8 100755
--- a/t/t3420-rebase-topology-linear.sh
+++ b/t/t3420-rebase-topology-linear.sh
@@ -218,4 +218,133 @@ test_run_rebase failure -m
 test_run_rebase failure -i
 test_run_rebase failure -p
 
+#   m
+#  /
+# a---b---c---g
+#
+# x---y---B
+#
+# uppercase = cherry-picked
+# m = reverted b
+#
+# Reverted patches are there for tests to be able to check if a commit
+# that introduced the same change as another commit is
+# dropped. Without reverted commits, we could get false positives
+# because applying the patch succeeds, but simply results in no
+# changes.
+test_expect_success 'setup of linear history for test involving root' '
+   git checkout b &&
+   revert m b &&
+   git checkout --orphan disjoint &&
+   git rm -rf . &&
+   test_commit x &&
+   test_commit y &&
+   cherry_pick B b
+'
+
+test_run_rebase () {
+   result=$1
+   shift
+   test_expect_$result "rebase $* --onto --root" "
+   reset_rebase &&
+   git rebase $* --onto c --root y &&
+   test_cmp_rev c HEAD~2 &&
+   test_linear_range 'x y' c..
+   "
+}
+test_run_rebase success ''
+test_run_rebase failure -m
+test_run_rebase success -i
+test_run_rebase success -p
+
+test_run_rebase () {
+   result=$1
+   shift
+   test_expect_$result "rebase $* without --onto --root with disjoint 
history" "
+   reset_rebase &&
+   git rebase $* c y &&
+   test_cmp_rev c HEAD~2 &&
+   test_linear_range 'x y' c..
+   "
+}
+test_run_rebase success ''
+test_run_rebase failure -m
+test_run_rebase success -i
+test_run_rebase failure -p
+
+test_run_rebase () {
+   result=$1
+   shift
+   test_expect_$result "rebase $* --onto --root drops patch in onto" "
+   reset_rebase &&
+   git rebase $* --onto m --root B &&
+   test_cmp_rev m HEAD~2 &&
+   test_linear_range 'x y' m..
+   "
+}
+test_run_rebase success ''
+test_run_rebase failure -m
+test_run_rebase success -i
+test_run_rebase success -p
+
+test_run_rebase () {
+   result=$1
+   shift
+   test_expect_$result "rebase $* --onto --root with merge-base does not 
go to root" "
+   reset_rebase &&
+   git rebase $* --onto m --root g &&
+   test_cmp_rev m HEAD~2 &&
+   test_linear_range 'c g' m..
+   "
+}
+
+test_run_rebase success ''
+test_run_rebase success -m
+test_run_rebase success -i
+test_run_rebase failure -p
+
+test_run_rebase () {
+   result=$1
+   shift
+   test_expect_$result "rebase $* without --onto --root with disjoint 
history drops patch in onto" "
+   reset_rebase &&
+   git rebase $* m B &&
+   test_cmp_rev m HEAD~2 &&
+   test_linear_range 'x y' m..
+   "
+}
+test_run_rebase success ''
+test_run_rebase failure -m
+test_run_rebase success -i
+test_run_rebase failure -p
+
+test_run_rebase () {
+   result=$1
+   shift
+   test_expect_$result "rebase $* --root on linear history is a no-op" "
+   reset_rebase &&
+   git rebase $* --root c &&
+   test_cmp_rev c HEAD
+   "
+}
+test_run_rebase failure ''
+test_run_rebase failure -m
+test_run_rebase failure -i
+test_run_rebase failure -p
+
+test_run_rebase () {
+   result=$1
+   shift
+   test_expect_$result "rebase $* -f --root on linear history causes 
re-write" "
+   reset_rebase &&
+   git rebase $* -f --root c &&
+   ! test_cmp_rev a HEAD~2 &&
+   test_linear_range 'a b c' HEAD
+   "
+}
+test_run_rebase success ''
+test_run_rebase success -m
+test_run_rebase success -i
+test_run_rebase success -p
+
 test_done
-- 
1.8.2.674.gd17d3d2

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


[PATCH v2 6/7] t3406: modernize style

2013-05-28 Thread Martin von Zweigbergk
Update the following:

 - Quote 'setup'
 - Remove blank lines within test case body
 - Use test_commit instead of custom quick_one
 - Create branch "topic" from tag created by test_commit
---
 t/t3406-rebase-message.sh | 30 +-
 1 file changed, 9 insertions(+), 21 deletions(-)

diff --git a/t/t3406-rebase-message.sh b/t/t3406-rebase-message.sh
index e6a9a0d..fe8c27f 100755
--- a/t/t3406-rebase-message.sh
+++ b/t/t3406-rebase-message.sh
@@ -4,27 +4,17 @@ test_description='messages from rebase operation'
 
 . ./test-lib.sh
 
-quick_one () {
-   echo "$1" >"file$1" &&
-   git add "file$1" &&
-   test_tick &&
-   git commit -m "$1"
-}
+test_expect_success 'setup' '
+   test_commit O fileO &&
+   test_commit X fileX &&
+   test_commit A fileA &&
+   test_commit B fileB &&
+   test_commit Y fileY &&
 
-test_expect_success setup '
-   quick_one O &&
-   git branch topic &&
-   quick_one X &&
-   quick_one A &&
-   quick_one B &&
-   quick_one Y &&
-
-   git checkout topic &&
-   quick_one A &&
-   quick_one B &&
-   quick_one Z &&
+   git checkout -b topic O &&
+   git cherry-pick A B &&
+   test_commit Z fileZ &&
git tag start
-
 '
 
 cat >expect <<\EOF
@@ -34,12 +24,10 @@ Committed: 0003 Z
 EOF
 
 test_expect_success 'rebase -m' '
-
git rebase -m master >report &&
sed -n -e "/^Already applied: /p" \
-e "/^Committed: /p" report >actual &&
test_cmp expect actual
-
 '
 
 test_expect_success 'rebase --stat' '
-- 
1.8.2.674.gd17d3d2

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


[PATCH v2 3/7] add tests for rebasing of empty commits

2013-05-28 Thread Martin von Zweigbergk
---
 t/t3401-rebase-partial.sh | 24 
 t/t3420-rebase-topology-linear.sh | 58 +++
 2 files changed, 58 insertions(+), 24 deletions(-)

diff --git a/t/t3401-rebase-partial.sh b/t/t3401-rebase-partial.sh
index 58f4823..7ba1797 100755
--- a/t/t3401-rebase-partial.sh
+++ b/t/t3401-rebase-partial.sh
@@ -42,28 +42,4 @@ test_expect_success 'rebase --merge topic branch that was 
partially merged upstr
test_path_is_missing .git/rebase-merge
 '
 
-test_expect_success 'rebase ignores empty commit' '
-   git reset --hard A &&
-   git commit --allow-empty -m empty &&
-   test_commit D &&
-   git rebase C &&
-   test "$(git log --format=%s C..)" = "D"
-'
-
-test_expect_success 'rebase --keep-empty' '
-   git reset --hard D &&
-   git rebase --keep-empty C &&
-   test "$(git log --format=%s C..)" = "D
-empty"
-'
-
-test_expect_success 'rebase --keep-empty keeps empty even if already in 
upstream' '
-   git reset --hard A &&
-   git commit --allow-empty -m also-empty &&
-   git rebase --keep-empty D &&
-   test "$(git log --format=%s A..)" = "also-empty
-D
-empty"
-'
-
 test_done
diff --git a/t/t3420-rebase-topology-linear.sh 
b/t/t3420-rebase-topology-linear.sh
index 1152491..40fe264 100755
--- a/t/t3420-rebase-topology-linear.sh
+++ b/t/t3420-rebase-topology-linear.sh
@@ -160,4 +160,62 @@ test_run_rebase failure -m
 test_run_rebase failure -i
 test_run_rebase failure -p
 
+# a---b---c---j!
+#  \
+#   d---k!--l
+#
+# ! = empty
+test_expect_success 'setup of linear history for empty commit tests' '
+   git checkout c &&
+   make_empty j &&
+   git checkout d &&
+   make_empty k &&
+   test_commit l
+'
+
+test_run_rebase () {
+   result=$1
+   shift
+   test_expect_$result "rebase $* drops empty commit" "
+   reset_rebase &&
+   git rebase $* c l &&
+   test_cmp_rev c HEAD~2 &&
+   test_linear_range 'd l' c..
+   "
+}
+test_run_rebase success ''
+test_run_rebase success -m
+test_run_rebase success -i
+test_run_rebase success -p
+
+test_run_rebase () {
+   result=$1
+   shift
+   test_expect_$result "rebase $* --keep-empty" "
+   reset_rebase &&
+   git rebase $* --keep-empty c l &&
+   test_cmp_rev c HEAD~3 &&
+   test_linear_range 'd k l' c..
+   "
+}
+test_run_rebase success ''
+test_run_rebase failure -m
+test_run_rebase success -i
+test_run_rebase failure -p
+
+test_run_rebase () {
+   result=$1
+   shift
+   test_expect_$result "rebase $* --keep-empty keeps empty even if already 
in upstream" "
+   reset_rebase &&
+   git rebase $* --keep-empty j l &&
+   test_cmp_rev j HEAD~3 &&
+   test_linear_range 'd k l' j..
+   "
+}
+test_run_rebase success ''
+test_run_rebase failure -m
+test_run_rebase failure -i
+test_run_rebase failure -p
+
 test_done
-- 
1.8.2.674.gd17d3d2

--
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: [RFC/PATCH v2 3/8] rebase: cherry-pick: fix sequence continuation

2013-05-28 Thread Martin von Zweigbergk
:-)

On Tue, May 28, 2013 at 11:05 PM, Felipe Contreras
 wrote:
> On Wed, May 29, 2013 at 12:51 AM, Martin von Zweigbergk
>  wrote:
>> On Tue, May 28, 2013 at 10:41 PM, Felipe Contreras
>>  wrote:
>
>>> One change splits, the other change fixes, what's wrong with that?
>>
>> I didn't say there was anything wrong. I was asking if the bug was
>> there before (and I didn't see an answer when Junio asked).
>
> Why wouldn't it be before? Did I mention a commit that introduced a
> problem? No. Did any patch in this series introduce a problem? No.
>
> All we've done in this series is 1) reorganize the code without
> introducing *ANY* functional changes, and 2) fix a bug.
>
> If you see 1) introducing a problem, or 2) introducing a problem, then
> mention that in *those* patches. If there is no problem with 1) or 2)
> then it follows the problem already exists.
>
> --
> Felipe Contreras
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC/PATCH v2 3/8] rebase: cherry-pick: fix sequence continuation

2013-05-28 Thread Martin von Zweigbergk
On Tue, May 28, 2013 at 10:41 PM, Felipe Contreras
 wrote:
> On Wed, May 29, 2013 at 12:33 AM, Martin von Zweigbergk
>  wrote:
>>  As Junio asked in the previous iteration, shouldn't this have been in
>> the first patch?
>
> No, the first patch is splitting the code without introducing any
> functional changes.
>
> This is fixing a bug that already exists, we could fix it before the
> split, or after, but mixing the split and the fix at the same time is
> a no-no.

Oh, now I remember. I ran into that bug once.

> One change splits, the other change fixes, what's wrong with that?

I didn't say there was anything wrong. I was asking if the bug was
there before (and I didn't see an answer when Junio asked).

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: [RFC/PATCH v2 2/8] rebase: cherry-pick: fix mode storage

2013-05-28 Thread Martin von Zweigbergk
Actually, are all of 2/8 - 7/8 fixes for things that broke in patch 1/8?

On Tue, May 28, 2013 at 9:16 PM, Felipe Contreras
 wrote:
> We don't use the 'rebase-apply'.
>
> Signed-off-by: Felipe Contreras 
> ---
>  git-rebase--cherrypick.sh | 4 
>  git-rebase.sh | 5 -
>  2 files changed, 8 insertions(+), 1 deletion(-)
>
> diff --git a/git-rebase--cherrypick.sh b/git-rebase--cherrypick.sh
> index cbf80f9..51354af 100644
> --- a/git-rebase--cherrypick.sh
> +++ b/git-rebase--cherrypick.sh
> @@ -18,6 +18,9 @@ esac
>
>  test -n "$rebase_root" && root_flag=--root
>
> +mkdir "$state_dir" || die "Could not create temporary $state_dir"
> +: > "$state_dir"/cherrypick || die "Could not mark as cherrypick"
> +
>  # we have to do this the hard way.  git format-patch completely squashes
>  # empty commits and even if it didn't the format doesn't really lend
>  # itself well to recording empty patches.  fortunately, cherry-pick
> @@ -32,3 +35,4 @@ then
>  fi
>
>  move_to_original_branch
> +rm -rf "$state_dir"
> diff --git a/git-rebase.sh b/git-rebase.sh
> index f929ca3..76900a0 100755
> --- a/git-rebase.sh
> +++ b/git-rebase.sh
> @@ -174,6 +174,9 @@ then
> then
> type=interactive
> interactive_rebase=explicit
> +   elif test -f "$merge_dir"/cherrypick
> +   then
> +   type=cherrypick
> else
> type=merge
> fi
> @@ -382,7 +385,7 @@ then
>  elif test -n "$keep_empty"
>  then
> type=cherrypick
> -   state_dir="$apply_dir"
> +   state_dir="$merge_dir"
>  else
> type=am
> state_dir="$apply_dir"
> --
> 1.8.3.rc3.312.g47657de
>
--
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: [RFC/PATCH v2 4/8] rebase: cherry-pick: fix abort of cherry mode

2013-05-28 Thread Martin von Zweigbergk
Same here: should this have been in the first patch? If not, do you
know for how long it has been broken (since which commit)?

On Tue, May 28, 2013 at 9:16 PM, Felipe Contreras
 wrote:
> Signed-off-by: Felipe Contreras 
> ---
>  git-rebase.sh | 1 +
>  1 file changed, 1 insertion(+)
>
> diff --git a/git-rebase.sh b/git-rebase.sh
> index 76900a0..9b5d78b 100755
> --- a/git-rebase.sh
> +++ b/git-rebase.sh
> @@ -335,6 +335,7 @@ skip)
> run_specific_rebase
> ;;
>  abort)
> +   test "$type" == "cherrypick" && git cherry-pick --abort
> git rerere clear
> read_basic_state
> case "$head_name" in
> --
> 1.8.3.rc3.312.g47657de
>
--
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: [RFC/PATCH v2 3/8] rebase: cherry-pick: fix sequence continuation

2013-05-28 Thread Martin von Zweigbergk
 As Junio asked in the previous iteration, shouldn't this have been in
the first patch?

On Tue, May 28, 2013 at 9:16 PM, Felipe Contreras
 wrote:
> We are not in am mode.
>
> Signed-off-by: Felipe Contreras 
> ---
>  git-rebase--cherrypick.sh | 10 ++
>  1 file changed, 6 insertions(+), 4 deletions(-)
>
> diff --git a/git-rebase--cherrypick.sh b/git-rebase--cherrypick.sh
> index 51354af..2fa4993 100644
> --- a/git-rebase--cherrypick.sh
> +++ b/git-rebase--cherrypick.sh
> @@ -5,13 +5,15 @@
>
>  case "$action" in
>  continue)
> -   git am --resolved --resolvemsg="$resolvemsg" &&
> -   move_to_original_branch
> +   git cherry-pick --continue &&
> +   move_to_original_branch &&
> +   rm -rf "$state_dir"
> exit
> ;;
>  skip)
> -   git am --skip --resolvemsg="$resolvemsg" &&
> -   move_to_original_branch
> +   git cherry-pick --skip &&
> +   move_to_original_branch &&
> +   rm -rf "$state_dir"
> exit
> ;;
>  esac
> --
> 1.8.3.rc3.312.g47657de
>
--
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 0/5] rebase: improve the keep-empty

2013-05-28 Thread Martin von Zweigbergk
Hi,

I think I have some patches at home that instead teach 'git am' the
--keep-empty flag. Does that make sense? It's been a while since I
looked at it, but I'll try to take a look tonight (PST).

Martin

On Tue, May 28, 2013 at 6:29 AM, Felipe Contreras
 wrote:
> Hi,
>
> I've been analyzing 'git rebase' and found that the --keep-empty option
> triggers a very very different behavior. Here's a bunch of patches that make 
> it
> behave like the 'am' does does for the most part.
>
> There's only a few minor changes, after which it might be possible to replace
> the whole 'am' mode to use cherr-pick instead.
>
> Felipe Contreras (5):
>   rebase: split the cherry-pick stuff
>   rebase: fix 'cherry' mode storage
>   rebase: fix sequence continuation
>   rebase: fix abort of cherry mode
>   rebase: fix cherry-pick invocations
>
>  .gitignore|  1 +
>  Makefile  |  1 +
>  git-rebase--am.sh | 65 
> ++-
>  git-rebase--cherry.sh | 55 +++
>  git-rebase.sh |  8 +++
>  5 files changed, 93 insertions(+), 37 deletions(-)
>  create mode 100644 git-rebase--cherry.sh
>
> --
> 1.8.3.rc3.312.g47657de
>
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 5/7] rebase -i: return control to the caller, for housekeeping

2013-04-23 Thread Martin von Zweigbergk
On Tue, Apr 23, 2013 at 7:02 AM, Ramkumar Ramachandra
 wrote:
> diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh
> index cc3a9a7..9514e31 100644
> --- a/git-rebase--interactive.sh
> +++ b/git-rebase--interactive.sh
> @@ -597,7 +597,7 @@ do_next () {
> fi
> ;;
> esac
> -   test -s "$todo" && return
> +   test -s "$todo" && return 1

Unlike the other cases below, this seems to be replacing success by
failure. What does it mean in practice that $todo is empty?

> comment_for_reflog finish &&
> newhead=$(git rev-parse HEAD) &&
> @@ -623,17 +623,15 @@ do_next () {
> "$GIT_DIR"/hooks/post-rewrite rebase < "$rewritten_list"
> true # we don't care if this hook failed
> fi &&
> -   rm -rf "$state_dir" &&
> -   git gc --auto &&
> warn "Successfully rebased and updated $head_name."
>
> -   exit
> +   return 0

So after this patch, the "warning" will coming before gc is run. It's
a change, but it seems fine. gc usually only prints a few line, right?

>  }
>
>  do_rest () {
> while :
> do
> -   do_next
> +   do_next && break
> done
>  }

Normally one would break if unsuccessful. What would fail if this was
replaced by "do_next || break" and the above ".. && return 1" was "..
&& return". I assume that was your first attempt, but why did it not
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: [PATCH 2/7] rebase -i: don't error out if $state_dir already exists

2013-04-23 Thread Martin von Zweigbergk
On Tue, Apr 23, 2013 at 7:01 AM, Ramkumar Ramachandra
 wrote:
> Practically speaking, the only reason why a `mkdir $state_dir` would
> fail is because $state_dir already exists.

Would we ever get to this point in the code if it already exists?

Also, I had the feeling that the check it might fail if the user does
not have permissions to create the directory. Is there always
something else that will fail first?
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 1/7] am: suppress error output from a conditional

2013-04-23 Thread Martin von Zweigbergk
On Tue, Apr 23, 2013 at 7:01 AM, Ramkumar Ramachandra
 wrote:
> When testing if the $dotest directory exists, and if $next is greater
> than $last

When can that happen? If one edits the todo?
--
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: `git checkout --orpan` leaves a dirty worktree

2013-02-08 Thread Martin von Zweigbergk
I'm curious what your use case is.

The behavior has been inconvenient for me too, but I have only used it
in test cases; I have no real use case where I wanted to create an
unborn/orphan branch.

On Fri, Feb 8, 2013 at 11:50 AM, Ramkumar Ramachandra
 wrote:
> Hi,
>
> Why should I have to `git rm -rf .` after a `git checkout --orphan`?
> What sort of misfeature/ incomplete feature is this?
>
> Ram
> --
> 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
--
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] rebase --preserve-merges keeps empty merge commits

2013-02-02 Thread Martin von Zweigbergk
On Fri, Feb 1, 2013 at 1:05 PM, Phil Hord  wrote:
>
> This is probably right, but it is not exactly the case that caused my itch.
> I think my branch looked like [...]

That also makes sense. I'll add tests for both cases. Your patch makes
both of them pass.

>> # a---b---c
>> #  \   \
>> #   d   \
>> #\   \
>> # e   \
>> #  \   \
>> #   C---l
>>
>> As you say, your patch doesn't try to handle this case, but at least
>> the new behavior seems better. I think we would ideally want the
>> recreated 'l' to have only 'C' as parent in this case. Does that make
>> sense?
>
> This is not what I meant, but it is a very interesting corner case.  I
> am not sure I have a solid opinion on what the result should be here.

Neither do I, so I'll just drop the test case. Thanks.

> Here is the corner case I was thinking of.  I did not test this to see
> if this will happen, but I conceived that it might.  Suppose you have
> this tree where
>
> # a---b---c
> #  \
> #   d---g---l
> #\ /
> # C
>
> where 'C' introduced the same changes as 'c'.
>
> When I execute 'git rebase -p l c', I expect that I will end up with
> this:
>
> # a---b---c---d---
> #  \  \
> #   ---g---l
>
> That is, 'C' gets skipped because it introduces the same changes already
> seen in 'c'.  So 'g' now has two parents: 'd' and 'C^'.  But 'C^' is 'd',
> so 'g' now has two parents, both of whom are 'd'.
>
> I think it should collapse to this instead:
>
> # a---b---c---d---g---l

I think this is actually what you will get. But I think it will only
be linearized if the branch that should be dropped is the second
parent. I have two tests for this, but I need to simplify them a
little to see that that (parent number) is the only difference.

> I hope this is clear, but please let me know if I made it too confusing.

Very clear. 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: [PATCH] rebase --preserve-merges keeps empty merge commits

2013-02-01 Thread Martin von Zweigbergk
I'm working on a re-roll of

http://thread.gmane.org/gmane.comp.version-control.git/205796

and finally got around to including test cases for what you fixed in
this patch. I want to make sure I'm testing what you fixed here. See
questions below.

On Sat, Jan 12, 2013 at 12:46 PM, Phil Hord  wrote:
> Since 90e1818f9a  (git-rebase: add keep_empty flag, 2012-04-20)
> 'git rebase --preserve-merges' fails to preserve empty merge commits
> unless --keep-empty is also specified.  Merge commits should be
> preserved in order to preserve the structure of the rebased graph,
> even if the merge commit does not introduce changes to the parent.
>
> Teach rebase not to drop merge commits only because they are empty.

Consider a history like

# a---b---c
#  \   \
#   d---l
#\
# e
#  \
#   C

where 'l' is tree-same with 'd' and 'C' introduces the same change as 'c'.

My test case runs 'git rebase -p e l' and expects the result to look like

# a---b---c
#  \   \
#   d   \
#\   \
# e---l

> A special case which is not handled by this change is for a merge commit
> whose parents are now the same commit because all the previous different
> parents have been dropped as a result of this rebase or some previous
> operation.

And for this case, the test case runs 'git rebase -p C l'. Is that
what you meant here?

Before your patch, git would just say "Nothing to do" and after your
patch, we get

# a---b---c
#  \   \
#   d   \
#\   \
# e   \
#  \   \
#   C---l

As you say, your patch doesn't try to handle this case, but at least
the new behavior seems better. I think we would ideally want the
recreated 'l' to have only 'C' as parent in this case. Does that make
sense?

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


Re: [PATCH 1/3] git-am: record full index line in the patch used while rebasing

2013-01-31 Thread Martin von Zweigbergk
On Thu, Jan 31, 2013 at 8:32 PM, Junio C Hamano  wrote:
> Earlier, a230949 (am --rebasing: get patch body from commit, not
> from mailbox, 2012-06-26) learned to regenerate patch body from the
> commit object while rebasing, instead of reading from the rebase-am
> front-end.  While doing so, it used "git diff-tree" but without
> giving it the "--full-index" option.
>
> This does not matter for in-repository objects; during rebasing, any
> abbreviated object name should uniquely identify them.
>
> But we may be rebasing a commit that contains a change to a gitlink,
> in which case we usually should not have the object (it names a
> commit in the submodule).  A full object name is necessary to later
> reconstruct a fake ancestor index for them.

>From what I can understand, this all makes sense. I didn't notice the
emails about the breakage until now, but I wouldn't have known where
to even start looking anyway, so thanks a lot for taking care of it.
--
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 08/31] parse_pathspec: add PATHSPEC_EMPTY_MATCH_ALL

2013-01-21 Thread Martin von Zweigbergk
Hi,

I was tempted to ask this before, and the recent thread regarding "add
-u/A" [1] convinced me to.

On Sun, Jan 13, 2013 at 4:35 AM, Nguyễn Thái Ngọc Duy  wrote:
> We have two ways of dealing with empty pathspec:
>
> 1. limit it to current prefix
> 2. match the entire working directory
>
> Some commands go with #1, some with #2. get_pathspec() and
> parse_pathspec() only supports #1. Make it support #2 too via
> PATHSPEC_EMPTY_MATCH_ALL flag.

If #2 is indeed the direction we want to go, then maybe we should make
that the default behavior from parse_pathspec()? I.e. rename the flag
"PATHSPEC_EMPTY_MATCH_PREFIX" (or something). Makes sense?

Btw, Matthieu was asking where we use #1. If you do invert the name
and meaning of the flag, then the answer to that question should be
(mostly?) obvious from a re-roll of your series (i.e. all the places
where PATHSPEC_EMPTY_MATCH_PREFIX is used).

Martin

 [1] http://thread.gmane.org/gmane.comp.version-control.git/213988/focus=214113
--
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: [RFC] git rm -u

2013-01-20 Thread Martin von Zweigbergk
On Sun, Jan 20, 2013 at 1:27 PM, Junio C Hamano  wrote:
> Junio C Hamano  writes:
>
>> Matthieu Moy  writes:
>>
>>> "git add -u" is one of the only exceptions (with "git grep"). I consider
>>> this as a bug, and think this should be changed. This has been discussed
>>> several times here, but no one took the time to actually do the change
>
>  - As we have the "from the root" magic pathspec these days,
>requiring "git add -u :/" when the user really means to add
>everything is no longer too much of a burden, but if we suddenly
>changed "git add -u" to mean "git add -u .", that is too much of
>a change in the semantics.

And I think someone (Jeff?) pointed out that that last part is even
more true for "git clean", which also currently works on the current
directory if not told otherwise.
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2 17/19] fixup! reset $sha1 $pathspec: require $sha1 only to be treeish

2013-01-16 Thread Martin von Zweigbergk
On Wed, Jan 16, 2013 at 10:00 AM, Martin von Zweigbergk
 wrote:
> ---
>
> Sorry, I forgot the documentation updates. I hope this looks ok. Can
> you squash this in, Junio? Thanks.

I see the series just entered 'next', so I guess it would have to go
on top then. Perhaps with a commit message like as simple as the
following. Let me know if you prefer it to be resent as a proper
patch. Sorry about the noise.

reset: update documentation to require only tree-ish with paths

When resetting with paths, we no longer require a commit argument, but
only a tree-ish. Update the documentation and synopsis accordingly.
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 17/19] fixup! reset $sha1 $pathspec: require $sha1 only to be treeish

2013-01-16 Thread Martin von Zweigbergk
---

Sorry, I forgot the documentation updates. I hope this looks ok. Can
you squash this in, Junio? Thanks.

I don't think any documentation update is necessary for the "reset on
unborn branch" patch. Let me know if you think differently.


 Documentation/git-reset.txt | 18 +-
 builtin/reset.c |  4 ++--
 2 files changed, 11 insertions(+), 11 deletions(-)

diff --git a/Documentation/git-reset.txt b/Documentation/git-reset.txt
index 978d8da..a404b47 100644
--- a/Documentation/git-reset.txt
+++ b/Documentation/git-reset.txt
@@ -8,20 +8,20 @@ git-reset - Reset current HEAD to the specified state
 SYNOPSIS
 
 [verse]
-'git reset' [-q] [] [--] ...
-'git reset' (--patch | -p) [] [--] [...]
+'git reset' [-q] [] [--] ...
+'git reset' (--patch | -p) [] [--] [...]
 'git reset' [--soft | --mixed | --hard | --merge | --keep] [-q] []
 
 DESCRIPTION
 ---
-In the first and second form, copy entries from  to the index.
+In the first and second form, copy entries from  to the index.
 In the third form, set the current branch head (HEAD) to , optionally
-modifying index and working tree to match.  The  defaults to HEAD
-in all forms.
+modifying index and working tree to match.  The / defaults
+to HEAD in all forms.
 
-'git reset' [-q] [] [--] ...::
+'git reset' [-q] [] [--] ...::
This form resets the index entries for all  to their
-   state at .  (It does not affect the working tree, nor
+   state at .  (It does not affect the working tree, nor
the current branch.)
 +
 This means that `git reset ` is the opposite of `git add
@@ -34,9 +34,9 @@ Alternatively, using linkgit:git-checkout[1] and specifying a 
commit, you
 can copy the contents of a path out of a commit to the index and to the
 working tree in one go.
 
-'git reset' (--patch | -p) [] [--] [...]::
+'git reset' (--patch | -p) [] [--] [...]::
Interactively select hunks in the difference between the index
-   and  (defaults to HEAD).  The chosen hunks are applied
+   and  (defaults to HEAD).  The chosen hunks are applied
in reverse to the index.
 +
 This means that `git reset -p` is the opposite of `git add -p`, i.e.
diff --git a/builtin/reset.c b/builtin/reset.c
index b776867..cb84f1b 100644
--- a/builtin/reset.c
+++ b/builtin/reset.c
@@ -23,8 +23,8 @@
 
 static const char * const git_reset_usage[] = {
N_("git reset [--mixed | --soft | --hard | --merge | --keep] [-q] 
[]"),
-   N_("git reset [-q]  [--] ..."),
-   N_("git reset --patch [] [--] [...]"),
+   N_("git reset [-q]  [--] ..."),
+   N_("git reset --patch [] [--] [...]"),
NULL
 };
 
-- 
1.8.1.1.454.gce43f05

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


Re: [PATCH v2 06/19] reset.c: remove unnecessary variable 'i'

2013-01-15 Thread Martin von Zweigbergk
I suppose this was meant for everyone. Adding back the others.

On Tue, Jan 15, 2013 at 10:27 AM, Holding, Lawrence (NZ)
 wrote:
> Maybe use *argv instead of argv[0]?

Sure. Everywhere? Also in the lines added in patch 17/19 that refer to
both argv[0] and argv[1], such as "argv[1] &&
!get_sha1_treeish(argv[0], unused)"? Or is this just a sign that I'm
making the code _more_ confusing to those who are more familiar with
C?
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 06/19] reset.c: remove unnecessary variable 'i'

2013-01-14 Thread Martin von Zweigbergk
Throughout most of parse_args(), the variable 'i' remains at 0. Many
references are still made to the variable even when it could only have
the value 0. This made at least me, who has relatively little
experience with C programming styles, think that parts of the function
was meant to be part of a loop. To avoid such confusion, remove the
variable and also the 'argc' parameter and check for NULL trailing
argv instead.

Signed-off-by: Martin von Zweigbergk 
---
I explained a bit more why I was confused by the current style, but
I'm also perfectly happy if you just drop the patch (there would be
some minor conflicts in a later patch, though).

 builtin/reset.c | 33 -
 1 file changed, 16 insertions(+), 17 deletions(-)

diff --git a/builtin/reset.c b/builtin/reset.c
index 58f0f61..d89cf4d 100644
--- a/builtin/reset.c
+++ b/builtin/reset.c
@@ -198,9 +198,8 @@ static void die_if_unmerged_cache(int reset_type)
 
 }
 
-static const char **parse_args(int argc, const char **argv, const char 
*prefix, const char **rev_ret)
+static const char **parse_args(const char **argv, const char *prefix, const 
char **rev_ret)
 {
-   int i = 0;
const char *rev = "HEAD";
unsigned char unused[20];
/*
@@ -211,34 +210,34 @@ static const char **parse_args(int argc, const char 
**argv, const char *prefix,
 * git reset [-opts] -- ...
 * git reset [-opts] ...
 *
-* At this point, argv[i] points immediately after [-opts].
+* At this point, argv points immediately after [-opts].
 */
 
-   if (i < argc) {
-   if (!strcmp(argv[i], "--")) {
-   i++; /* reset to HEAD, possibly with paths */
-   } else if (i + 1 < argc && !strcmp(argv[i+1], "--")) {
-   rev = argv[i];
-   i += 2;
+   if (argv[0]) {
+   if (!strcmp(argv[0], "--")) {
+   argv++; /* reset to HEAD, possibly with paths */
+   } else if (argv[1] && !strcmp(argv[1], "--")) {
+   rev = argv[0];
+   argv += 2;
}
/*
-* Otherwise, argv[i] could be either  or  and
+* Otherwise, argv[0] could be either  or  and
 * has to be unambiguous.
 */
-   else if (!get_sha1_committish(argv[i], unused)) {
+   else if (!get_sha1_committish(argv[0], unused)) {
/*
-* Ok, argv[i] looks like a rev; it should not
+* Ok, argv[0] looks like a rev; it should not
 * be a filename.
 */
-   verify_non_filename(prefix, argv[i]);
-   rev = argv[i++];
+   verify_non_filename(prefix, argv[0]);
+   rev = *argv++;
} else {
/* Otherwise we treat this as a filename */
-   verify_filename(prefix, argv[i], 1);
+   verify_filename(prefix, argv[0], 1);
}
}
*rev_ret = rev;
-   return i < argc ? get_pathspec(prefix, argv + i) : NULL;
+   return argv[0] ? get_pathspec(prefix, argv) : NULL;
 }
 
 int cmd_reset(int argc, const char **argv, const char *prefix)
@@ -270,7 +269,7 @@ int cmd_reset(int argc, const char **argv, const char 
*prefix)
 
argc = parse_options(argc, argv, prefix, options, git_reset_usage,
PARSE_OPT_KEEP_DASHDASH);
-   pathspec = parse_args(argc, argv, prefix, &rev);
+   pathspec = parse_args(argv, prefix, &rev);
 
if (get_sha1_committish(rev, sha1))
die(_("Failed to resolve '%s' as a valid ref."), rev);
-- 
1.8.1.1.454.gce43f05

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


[PATCH v2 08/19] reset.c: share call to die_if_unmerged_cache()

2013-01-14 Thread Martin von Zweigbergk
Use a single condition to guard the call to die_if_unmerged_cache for
both --soft and --keep. This avoids the small distraction of the
precondition check from the logic following it.

Also change an instance of

  if (e)
err = err || f();

to the almost as short, but clearer

  if (e && !err)
err = f();

(which is equivalent since we only care whether exit code is 0)

Signed-off-by: Martin von Zweigbergk 
---
 builtin/reset.c | 14 ++
 1 file changed, 6 insertions(+), 8 deletions(-)

diff --git a/builtin/reset.c b/builtin/reset.c
index 2187d64..4e34195 100644
--- a/builtin/reset.c
+++ b/builtin/reset.c
@@ -337,15 +337,13 @@ int cmd_reset(int argc, const char **argv, const char 
*prefix)
/* Soft reset does not touch the index file nor the working tree
 * at all, but requires them in a good order.  Other resets reset
 * the index file to the tree object we are switching to. */
-   if (reset_type == SOFT)
+   if (reset_type == SOFT || reset_type == KEEP)
die_if_unmerged_cache(reset_type);
-   else {
-   int err;
-   if (reset_type == KEEP)
-   die_if_unmerged_cache(reset_type);
-   err = reset_index_file(sha1, reset_type, quiet);
-   if (reset_type == KEEP)
-   err = err || reset_index_file(sha1, MIXED, quiet);
+
+   if (reset_type != SOFT) {
+   int err = reset_index_file(sha1, reset_type, quiet);
+   if (reset_type == KEEP && !err)
+   err = reset_index_file(sha1, MIXED, quiet);
if (err)
die(_("Could not reset index file to revision '%s'."), 
rev);
}
-- 
1.8.1.1.454.gce43f05

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


[PATCH v2 12/19] reset.c: move update_index_refresh() call out of read_from_tree()

2013-01-14 Thread Martin von Zweigbergk
The final part of cmd_reset() essentially looks like:

  if (pathspec) {
...
read_from_tree(...);
  } else {
...
reset_index(...);
update_index_refresh(...);
...
  }

where read_from_tree() internally also calls
update_index_refresh(). Move the call to update_index_refresh() out of
read_from_tree for symmetry with the 'else' block, making
read_from_tree() and reset_index() closer in functionality.

Signed-off-by: Martin von Zweigbergk 
---
 builtin/reset.c | 18 +-
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/builtin/reset.c b/builtin/reset.c
index c3eb2eb..70733c2 100644
--- a/builtin/reset.c
+++ b/builtin/reset.c
@@ -145,11 +145,8 @@ static void update_index_from_diff(struct 
diff_queue_struct *q,
}
 }
 
-static int read_from_tree(const char **pathspec, unsigned char *tree_sha1,
- int refresh_flags)
+static int read_from_tree(const char **pathspec, unsigned char *tree_sha1)
 {
-   struct lock_file *lock = xcalloc(1, sizeof(struct lock_file));
-   int index_fd;
struct diff_options opt;
 
memset(&opt, 0, sizeof(opt));
@@ -157,7 +154,6 @@ static int read_from_tree(const char **pathspec, unsigned 
char *tree_sha1,
opt.output_format = DIFF_FORMAT_CALLBACK;
opt.format_callback = update_index_from_diff;
 
-   index_fd = hold_locked_index(lock, 1);
read_cache();
if (do_diff_cache(tree_sha1, &opt))
return 1;
@@ -165,7 +161,7 @@ static int read_from_tree(const char **pathspec, unsigned 
char *tree_sha1,
diff_flush(&opt);
diff_tree_release_paths(&opt);
 
-   return update_index_refresh(index_fd, lock, refresh_flags);
+   return 0;
 }
 
 static void set_reflog_message(struct strbuf *sb, const char *action,
@@ -322,9 +318,13 @@ int cmd_reset(int argc, const char **argv, const char 
*prefix)
die(_("%s reset is not allowed in a bare repository"),
_(reset_type_names[reset_type]));
 
-   if (pathspec)
-   return read_from_tree(pathspec, sha1,
-   quiet ? REFRESH_QUIET : REFRESH_IN_PORCELAIN);
+   if (pathspec) {
+   struct lock_file *lock = xcalloc(1, sizeof(struct lock_file));
+   int index_fd = hold_locked_index(lock, 1);
+   return read_from_tree(pathspec, sha1) ||
+   update_index_refresh(index_fd, lock,
+   quiet ? REFRESH_QUIET : 
REFRESH_IN_PORCELAIN);
+   }
 
/* Soft reset does not touch the index file nor the working tree
 * at all, but requires them in a good order.  Other resets reset
-- 
1.8.1.1.454.gce43f05

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


[PATCH v2 00/19] reset improvements

2013-01-14 Thread Martin von Zweigbergk
Changes since v1:

 - Spelling fixes.

 - Explained how "git reset -- $pathspec" in bare repo is broken.

 - Provided motivation for replacement of switch by if-else

 - Fixed argv/argc handling by removing use of argc.

 - Replaced "don't refresh index on --quiet" patch by one that just
   inlines update_index_refresh()

 - Incorporated fixes from Junio's repo

 - Provided some motivation for "replace switch by if-else" amd moved
   the patch later in the series.

Thanks for reviewing!


Martin von Zweigbergk (19):
  reset $pathspec: no need to discard index
  reset $pathspec: exit with code 0 if successful
  reset.c: pass pathspec around instead of (prefix, argv) pair
  reset: don't allow "git reset -- $pathspec" in bare repo
  reset.c: extract function for parsing arguments
  reset.c: remove unnecessary variable 'i'
  reset.c: extract function for updating {ORIG_,}HEAD
  reset.c: share call to die_if_unmerged_cache()
  reset --keep: only write index file once
  reset: avoid redundant error message
  reset.c: replace switch by if-else
  reset.c: move update_index_refresh() call out of read_from_tree()
  reset.c: move lock, write and commit out of update_index_refresh()
  reset [--mixed]: only write index file once
  reset.c: finish entire cmd_reset() whether or not pathspec is given
  reset.c: inline update_index_refresh()
  reset $sha1 $pathspec: require $sha1 only to be treeish
  reset: allow reset on unborn branch
  reset [--mixed]: use diff-based reset whether or not pathspec was
given

 builtin/reset.c| 283 +++--
 t/t2013-checkout-submodule.sh  |   2 +-
 t/t7102-reset.sh   |  26 +++-
 t/t7106-reset-unborn-branch.sh |  52 
 4 files changed, 203 insertions(+), 160 deletions(-)
 create mode 100755 t/t7106-reset-unborn-branch.sh

-- 
1.8.1.1.454.gce43f05

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


[PATCH v2 09/19] reset --keep: only write index file once

2013-01-14 Thread Martin von Zweigbergk
"git reset --keep" calls reset_index_file() twice, first doing a
two-way merge to the target revision, updating the index and worktree,
and then resetting the index. After each call, we write the index
file.

In the unlikely event that the second call to reset_index_file()
fails, the index will have been merged to the target revision, but
HEAD will not be updated, leaving the user with a dirty index.

By moving the locking, writing and committing out of
reset_index_file() and into the caller, we can avoid writing the index
twice, thereby making the sure we don't end up in the half-way reset
state. As a bonus, we speed up "git reset --keep" a little on the
linux-2.6 repo (best of five, warm cache):

Before  After
real0m0.315s0m0.296s
user0m0.290s0m0.280s
sys 0m0.020s0m0.010s

Signed-off-by: Martin von Zweigbergk 
---
 builtin/reset.c | 21 ++---
 1 file changed, 10 insertions(+), 11 deletions(-)

diff --git a/builtin/reset.c b/builtin/reset.c
index 4e34195..7c440ad 100644
--- a/builtin/reset.c
+++ b/builtin/reset.c
@@ -38,14 +38,12 @@ static inline int is_merge(void)
return !access(git_path("MERGE_HEAD"), F_OK);
 }
 
-static int reset_index_file(const unsigned char *sha1, int reset_type, int 
quiet)
+static int reset_index(const unsigned char *sha1, int reset_type, int quiet)
 {
int nr = 1;
-   int newfd;
struct tree_desc desc[2];
struct tree *tree;
struct unpack_trees_options opts;
-   struct lock_file *lock = xcalloc(1, sizeof(struct lock_file));
 
memset(&opts, 0, sizeof(opts));
opts.head_idx = 1;
@@ -67,8 +65,6 @@ static int reset_index_file(const unsigned char *sha1, int 
reset_type, int quiet
opts.reset = 1;
}
 
-   newfd = hold_locked_index(lock, 1);
-
read_cache_unmerged();
 
if (reset_type == KEEP) {
@@ -91,10 +87,6 @@ static int reset_index_file(const unsigned char *sha1, int 
reset_type, int quiet
prime_cache_tree(&active_cache_tree, tree);
}
 
-   if (write_cache(newfd, active_cache, active_nr) ||
-   commit_locked_index(lock))
-   return error(_("Could not write new index file."));
-
return 0;
 }
 
@@ -341,9 +333,16 @@ int cmd_reset(int argc, const char **argv, const char 
*prefix)
die_if_unmerged_cache(reset_type);
 
if (reset_type != SOFT) {
-   int err = reset_index_file(sha1, reset_type, quiet);
+   struct lock_file *lock = xcalloc(1, sizeof(struct lock_file));
+   int newfd = hold_locked_index(lock, 1);
+   int err = reset_index(sha1, reset_type, quiet);
if (reset_type == KEEP && !err)
-   err = reset_index_file(sha1, MIXED, quiet);
+   err = reset_index(sha1, MIXED, quiet);
+   if (!err &&
+   (write_cache(newfd, active_cache, active_nr) ||
+commit_locked_index(lock))) {
+   err = error(_("Could not write new index file."));
+   }
if (err)
die(_("Could not reset index file to revision '%s'."), 
rev);
}
-- 
1.8.1.1.454.gce43f05

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


[PATCH v2 07/19] reset.c: extract function for updating {ORIG_,}HEAD

2013-01-14 Thread Martin von Zweigbergk
By extracting the code for updating the HEAD and ORIG_HEAD symbolic
references to a separate function, we declutter cmd_reset() a bit and
we make it clear that e.g. the four variables {,sha1_}{,old_}orig are
only used by this code.

Signed-off-by: Martin von Zweigbergk 
---
 builtin/reset.c | 39 +++
 1 file changed, 23 insertions(+), 16 deletions(-)

diff --git a/builtin/reset.c b/builtin/reset.c
index d89cf4d..2187d64 100644
--- a/builtin/reset.c
+++ b/builtin/reset.c
@@ -240,16 +240,35 @@ static const char **parse_args(const char **argv, const 
char *prefix, const char
return argv[0] ? get_pathspec(prefix, argv) : NULL;
 }
 
+static int update_refs(const char *rev, const unsigned char *sha1)
+{
+   int update_ref_status;
+   struct strbuf msg = STRBUF_INIT;
+   unsigned char *orig = NULL, sha1_orig[20],
+   *old_orig = NULL, sha1_old_orig[20];
+
+   if (!get_sha1("ORIG_HEAD", sha1_old_orig))
+   old_orig = sha1_old_orig;
+   if (!get_sha1("HEAD", sha1_orig)) {
+   orig = sha1_orig;
+   set_reflog_message(&msg, "updating ORIG_HEAD", NULL);
+   update_ref(msg.buf, "ORIG_HEAD", orig, old_orig, 0, MSG_ON_ERR);
+   } else if (old_orig)
+   delete_ref("ORIG_HEAD", old_orig, 0);
+   set_reflog_message(&msg, "updating HEAD", rev);
+   update_ref_status = update_ref(msg.buf, "HEAD", sha1, orig, 0, 
MSG_ON_ERR);
+   strbuf_release(&msg);
+   return update_ref_status;
+}
+
 int cmd_reset(int argc, const char **argv, const char *prefix)
 {
int reset_type = NONE, update_ref_status = 0, quiet = 0;
int patch_mode = 0;
const char *rev;
-   unsigned char sha1[20], *orig = NULL, sha1_orig[20],
-   *old_orig = NULL, sha1_old_orig[20];
+   unsigned char sha1[20];
const char **pathspec = NULL;
struct commit *commit;
-   struct strbuf msg = STRBUF_INIT;
const struct option options[] = {
OPT__QUIET(&quiet, N_("be quiet, only report errors")),
OPT_SET_INT(0, "mixed", &reset_type,
@@ -333,17 +352,7 @@ int cmd_reset(int argc, const char **argv, const char 
*prefix)
 
/* Any resets update HEAD to the head being switched to,
 * saving the previous head in ORIG_HEAD before. */
-   if (!get_sha1("ORIG_HEAD", sha1_old_orig))
-   old_orig = sha1_old_orig;
-   if (!get_sha1("HEAD", sha1_orig)) {
-   orig = sha1_orig;
-   set_reflog_message(&msg, "updating ORIG_HEAD", NULL);
-   update_ref(msg.buf, "ORIG_HEAD", orig, old_orig, 0, MSG_ON_ERR);
-   }
-   else if (old_orig)
-   delete_ref("ORIG_HEAD", old_orig, 0);
-   set_reflog_message(&msg, "updating HEAD", rev);
-   update_ref_status = update_ref(msg.buf, "HEAD", sha1, orig, 0, 
MSG_ON_ERR);
+   update_ref_status = update_refs(rev, sha1);
 
switch (reset_type) {
case HARD:
@@ -360,7 +369,5 @@ int cmd_reset(int argc, const char **argv, const char 
*prefix)
 
remove_branch_state();
 
-   strbuf_release(&msg);
-
return update_ref_status;
 }
-- 
1.8.1.1.454.gce43f05

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


[PATCH v2 16/19] reset.c: inline update_index_refresh()

2013-01-14 Thread Martin von Zweigbergk
Now that there is only one caller left to the single-line method
update_index_refresh(), inline it.

Signed-off-by: Martin von Zweigbergk 
---
 builtin/reset.c | 14 +-
 1 file changed, 5 insertions(+), 9 deletions(-)

diff --git a/builtin/reset.c b/builtin/reset.c
index c316d9b..520c1a5 100644
--- a/builtin/reset.c
+++ b/builtin/reset.c
@@ -109,12 +109,6 @@ static void print_new_head_line(struct commit *commit)
printf("\n");
 }
 
-static void update_index_refresh(int flags)
-{
-   refresh_index(&the_index, (flags), NULL, NULL,
- _("Unstaged changes after reset:"));
-}
-
 static void update_index_from_diff(struct diff_queue_struct *q,
struct diff_options *opt, void *data)
 {
@@ -329,9 +323,11 @@ int cmd_reset(int argc, const char **argv, const char 
*prefix)
die(_("Could not reset index file to revision 
'%s'."), rev);
}
 
-   if (reset_type == MIXED) /* Report what has not been updated. */
-   update_index_refresh(
-   quiet ? REFRESH_QUIET : REFRESH_IN_PORCELAIN);
+   if (reset_type == MIXED) { /* Report what has not been updated. 
*/
+   int flags = quiet ? REFRESH_QUIET : 
REFRESH_IN_PORCELAIN;
+   refresh_index(&the_index, flags, NULL, NULL,
+ _("Unstaged changes after reset:"));
+   }
 
if (write_cache(newfd, active_cache, active_nr) ||
commit_locked_index(lock))
-- 
1.8.1.1.454.gce43f05

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


[PATCH v2 11/19] reset.c: replace switch by if-else

2013-01-14 Thread Martin von Zweigbergk
The switch statement towards the end of reset.c is missing case arms
for KEEP and MERGE for no obvious reason, and soon the only non-empty
case arm will be the one for HARD. So let's proactively replace it by
if-else, which will let us move one if statement out without leaving
funny-looking left-overs.

Signed-off-by: Martin von Zweigbergk 
---
 builtin/reset.c | 13 +++--
 1 file changed, 3 insertions(+), 10 deletions(-)

diff --git a/builtin/reset.c b/builtin/reset.c
index 97fa9f7..c3eb2eb 100644
--- a/builtin/reset.c
+++ b/builtin/reset.c
@@ -349,18 +349,11 @@ int cmd_reset(int argc, const char **argv, const char 
*prefix)
 * saving the previous head in ORIG_HEAD before. */
update_ref_status = update_refs(rev, sha1);
 
-   switch (reset_type) {
-   case HARD:
-   if (!update_ref_status && !quiet)
-   print_new_head_line(commit);
-   break;
-   case SOFT: /* Nothing else to do. */
-   break;
-   case MIXED: /* Report what has not been updated. */
+   if (reset_type == HARD && !update_ref_status && !quiet)
+   print_new_head_line(commit);
+   else if (reset_type == MIXED) /* Report what has not been updated. */
update_index_refresh(0, NULL,
quiet ? REFRESH_QUIET : REFRESH_IN_PORCELAIN);
-   break;
-   }
 
remove_branch_state();
 
-- 
1.8.1.1.454.gce43f05

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


[PATCH v2 05/19] reset.c: extract function for parsing arguments

2013-01-14 Thread Martin von Zweigbergk
Declutter cmd_reset() a bit by moving out the argument parsing to its
own function.

Signed-off-by: Martin von Zweigbergk 
---
 builtin/reset.c | 70 +++--
 1 file changed, 38 insertions(+), 32 deletions(-)

diff --git a/builtin/reset.c b/builtin/reset.c
index 664fad9..58f0f61 100644
--- a/builtin/reset.c
+++ b/builtin/reset.c
@@ -198,36 +198,11 @@ static void die_if_unmerged_cache(int reset_type)
 
 }
 
-int cmd_reset(int argc, const char **argv, const char *prefix)
+static const char **parse_args(int argc, const char **argv, const char 
*prefix, const char **rev_ret)
 {
-   int i = 0, reset_type = NONE, update_ref_status = 0, quiet = 0;
-   int patch_mode = 0;
+   int i = 0;
const char *rev = "HEAD";
-   unsigned char sha1[20], *orig = NULL, sha1_orig[20],
-   *old_orig = NULL, sha1_old_orig[20];
-   const char **pathspec = NULL;
-   struct commit *commit;
-   struct strbuf msg = STRBUF_INIT;
-   const struct option options[] = {
-   OPT__QUIET(&quiet, N_("be quiet, only report errors")),
-   OPT_SET_INT(0, "mixed", &reset_type,
-   N_("reset HEAD and index"), 
MIXED),
-   OPT_SET_INT(0, "soft", &reset_type, N_("reset only HEAD"), 
SOFT),
-   OPT_SET_INT(0, "hard", &reset_type,
-   N_("reset HEAD, index and working tree"), HARD),
-   OPT_SET_INT(0, "merge", &reset_type,
-   N_("reset HEAD, index and working tree"), 
MERGE),
-   OPT_SET_INT(0, "keep", &reset_type,
-   N_("reset HEAD but keep local changes"), KEEP),
-   OPT_BOOLEAN('p', "patch", &patch_mode, N_("select hunks 
interactively")),
-   OPT_END()
-   };
-
-   git_config(git_default_config, NULL);
-
-   argc = parse_options(argc, argv, prefix, options, git_reset_usage,
-   PARSE_OPT_KEEP_DASHDASH);
-
+   unsigned char unused[20];
/*
 * Possible arguments are:
 *
@@ -250,7 +225,7 @@ int cmd_reset(int argc, const char **argv, const char 
*prefix)
 * Otherwise, argv[i] could be either  or  and
 * has to be unambiguous.
 */
-   else if (!get_sha1_committish(argv[i], sha1)) {
+   else if (!get_sha1_committish(argv[i], unused)) {
/*
 * Ok, argv[i] looks like a rev; it should not
 * be a filename.
@@ -262,6 +237,40 @@ int cmd_reset(int argc, const char **argv, const char 
*prefix)
verify_filename(prefix, argv[i], 1);
}
}
+   *rev_ret = rev;
+   return i < argc ? get_pathspec(prefix, argv + i) : NULL;
+}
+
+int cmd_reset(int argc, const char **argv, const char *prefix)
+{
+   int reset_type = NONE, update_ref_status = 0, quiet = 0;
+   int patch_mode = 0;
+   const char *rev;
+   unsigned char sha1[20], *orig = NULL, sha1_orig[20],
+   *old_orig = NULL, sha1_old_orig[20];
+   const char **pathspec = NULL;
+   struct commit *commit;
+   struct strbuf msg = STRBUF_INIT;
+   const struct option options[] = {
+   OPT__QUIET(&quiet, N_("be quiet, only report errors")),
+   OPT_SET_INT(0, "mixed", &reset_type,
+   N_("reset HEAD and index"), 
MIXED),
+   OPT_SET_INT(0, "soft", &reset_type, N_("reset only HEAD"), 
SOFT),
+   OPT_SET_INT(0, "hard", &reset_type,
+   N_("reset HEAD, index and working tree"), HARD),
+   OPT_SET_INT(0, "merge", &reset_type,
+   N_("reset HEAD, index and working tree"), 
MERGE),
+   OPT_SET_INT(0, "keep", &reset_type,
+   N_("reset HEAD but keep local changes"), KEEP),
+   OPT_BOOLEAN('p', "patch", &patch_mode, N_("select hunks 
interactively")),
+   OPT_END()
+   };
+
+   git_config(git_default_config, NULL);
+
+   argc = parse_options(argc, argv, prefix, options, git_reset_usage,
+   PARSE_OPT_KEEP_DASHDASH);
+   pathspec = parse_args(argc, argv, prefix, &rev);
 
if (get_sha1_committish(rev, sha1))
die(_("Failed to resolve '%s' as a valid ref."), rev);
@@ -277,9 +286,6 @@ int cmd_reset(i

[PATCH v2 10/19] reset: avoid redundant error message

2013-01-14 Thread Martin von Zweigbergk
If writing or committing the new index file fails, we print "Could not
write new index file." followed by "Could not reset index file to
revision $rev.". The first message seems to imply the second, so print
only the first message.

Signed-off-by: Martin von Zweigbergk 
---
 builtin/reset.c | 8 +++-
 1 file changed, 3 insertions(+), 5 deletions(-)

diff --git a/builtin/reset.c b/builtin/reset.c
index 7c440ad..97fa9f7 100644
--- a/builtin/reset.c
+++ b/builtin/reset.c
@@ -338,13 +338,11 @@ int cmd_reset(int argc, const char **argv, const char 
*prefix)
int err = reset_index(sha1, reset_type, quiet);
if (reset_type == KEEP && !err)
err = reset_index(sha1, MIXED, quiet);
-   if (!err &&
-   (write_cache(newfd, active_cache, active_nr) ||
-commit_locked_index(lock))) {
-   err = error(_("Could not write new index file."));
-   }
if (err)
die(_("Could not reset index file to revision '%s'."), 
rev);
+   if (write_cache(newfd, active_cache, active_nr) ||
+   commit_locked_index(lock))
+   die(_("Could not write new index file."));
}
 
/* Any resets update HEAD to the head being switched to,
-- 
1.8.1.1.454.gce43f05

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


[PATCH v2 14/19] reset [--mixed]: only write index file once

2013-01-14 Thread Martin von Zweigbergk
When doing a mixed reset without paths, the index is locked, read,
reset, and written back as part of the actual reset operation (in
reset_index()). Then, when showing the list of worktree modifications,
we lock the index again, refresh it, and write it.

Change this so we only write the index once, making "git reset" a
little faster. It does mean that the index lock will be held a little
longer, but the difference is small compared to the time spent
refreshing the index.

There is one minor functional difference: We used to say "Could not
write new index file." if the first write failed, and "Could not
refresh index" if the second write failed. Now, we will only use the
first message.

This speeds up "git reset" a little on the linux-2.6 repo (best of
five, warm cache):

Before  After
real0m0.239s0m0.214s
user0m0.160s0m0.130s
sys     0m0.070s0m0.080s

Signed-off-by: Martin von Zweigbergk 
---
 builtin/reset.c | 14 +-
 1 file changed, 5 insertions(+), 9 deletions(-)

diff --git a/builtin/reset.c b/builtin/reset.c
index c1d6ef2..e8a3e41 100644
--- a/builtin/reset.c
+++ b/builtin/reset.c
@@ -336,6 +336,11 @@ int cmd_reset(int argc, const char **argv, const char 
*prefix)
err = reset_index(sha1, MIXED, quiet);
if (err)
die(_("Could not reset index file to revision '%s'."), 
rev);
+
+   if (reset_type == MIXED) /* Report what has not been updated. */
+   update_index_refresh(
+   quiet ? REFRESH_QUIET : REFRESH_IN_PORCELAIN);
+
if (write_cache(newfd, active_cache, active_nr) ||
commit_locked_index(lock))
die(_("Could not write new index file."));
@@ -347,15 +352,6 @@ int cmd_reset(int argc, const char **argv, const char 
*prefix)
 
if (reset_type == HARD && !update_ref_status && !quiet)
print_new_head_line(commit);
-   else if (reset_type == MIXED) { /* Report what has not been updated. */
-   struct lock_file *index_lock = xcalloc(1, sizeof(struct 
lock_file));
-   int fd = hold_locked_index(index_lock, 1);
-   update_index_refresh(
-   quiet ? REFRESH_QUIET : REFRESH_IN_PORCELAIN);
-   if (write_cache(fd, active_cache, active_nr) ||
-   commit_locked_index(index_lock))
-   error("Could not refresh index");
-   }
 
remove_branch_state();
 
-- 
1.8.1.1.454.gce43f05

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


[PATCH v2 15/19] reset.c: finish entire cmd_reset() whether or not pathspec is given

2013-01-14 Thread Martin von Zweigbergk
By not returning from inside the "if (pathspec)" block, we can let the
pathspec-aware and pathspec-less code share a bit more, making it
easier to make future changes that should affect both cases. This also
highlights the similarity between read_from_tree() and reset_index().

Signed-off-by: Martin von Zweigbergk 
---
 builtin/reset.c | 42 ++
 1 file changed, 18 insertions(+), 24 deletions(-)

diff --git a/builtin/reset.c b/builtin/reset.c
index e8a3e41..c316d9b 100644
--- a/builtin/reset.c
+++ b/builtin/reset.c
@@ -309,19 +309,6 @@ int cmd_reset(int argc, const char **argv, const char 
*prefix)
die(_("%s reset is not allowed in a bare repository"),
_(reset_type_names[reset_type]));
 
-   if (pathspec) {
-   struct lock_file *lock = xcalloc(1, sizeof(struct lock_file));
-   int index_fd = hold_locked_index(lock, 1);
-   if (read_from_tree(pathspec, sha1))
-   return 1;
-   update_index_refresh(
-   quiet ? REFRESH_QUIET : REFRESH_IN_PORCELAIN);
-   if (write_cache(index_fd, active_cache, active_nr) ||
-   commit_locked_index(lock))
-   return error("Could not write new index file.");
-   return 0;
-   }
-
/* Soft reset does not touch the index file nor the working tree
 * at all, but requires them in a good order.  Other resets reset
 * the index file to the tree object we are switching to. */
@@ -331,11 +318,16 @@ int cmd_reset(int argc, const char **argv, const char 
*prefix)
if (reset_type != SOFT) {
struct lock_file *lock = xcalloc(1, sizeof(struct lock_file));
int newfd = hold_locked_index(lock, 1);
-   int err = reset_index(sha1, reset_type, quiet);
-   if (reset_type == KEEP && !err)
-   err = reset_index(sha1, MIXED, quiet);
-   if (err)
-   die(_("Could not reset index file to revision '%s'."), 
rev);
+   if (pathspec) {
+   if (read_from_tree(pathspec, sha1))
+   return 1;
+   } else {
+   int err = reset_index(sha1, reset_type, quiet);
+   if (reset_type == KEEP && !err)
+   err = reset_index(sha1, MIXED, quiet);
+   if (err)
+   die(_("Could not reset index file to revision 
'%s'."), rev);
+   }
 
if (reset_type == MIXED) /* Report what has not been updated. */
update_index_refresh(
@@ -346,14 +338,16 @@ int cmd_reset(int argc, const char **argv, const char 
*prefix)
die(_("Could not write new index file."));
}
 
-   /* Any resets update HEAD to the head being switched to,
-* saving the previous head in ORIG_HEAD before. */
-   update_ref_status = update_refs(rev, sha1);
+   if (!pathspec) {
+   /* Any resets without paths update HEAD to the head being
+* switched to, saving the previous head in ORIG_HEAD before. */
+   update_ref_status = update_refs(rev, sha1);
 
-   if (reset_type == HARD && !update_ref_status && !quiet)
-   print_new_head_line(commit);
+   if (reset_type == HARD && !update_ref_status && !quiet)
+   print_new_head_line(commit);
 
-   remove_branch_state();
+   remove_branch_state();
+   }
 
return update_ref_status;
 }
-- 
1.8.1.1.454.gce43f05

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


[PATCH v2 13/19] reset.c: move lock, write and commit out of update_index_refresh()

2013-01-14 Thread Martin von Zweigbergk
In preparation for the/a following patch, move the locking, writing
and committing of the index file out of update_index_refresh(). The
code duplication caused will soon be taken care of. What remains of
update_index_refresh() is just one line, but it is still called from
two places, so let's leave it for now.

In the process, we expose and fix the minor UI bug that makes us print
"Could not refresh index" when we fail to write the index file when
invoked with a pathspec. Copy the error message from the pathspec-less
codepath ("Could not write new index file.").

Signed-off-by: Martin von Zweigbergk 
---
 builtin/reset.c | 34 ++
 1 file changed, 18 insertions(+), 16 deletions(-)

diff --git a/builtin/reset.c b/builtin/reset.c
index 70733c2..c1d6ef2 100644
--- a/builtin/reset.c
+++ b/builtin/reset.c
@@ -109,19 +109,10 @@ static void print_new_head_line(struct commit *commit)
printf("\n");
 }
 
-static int update_index_refresh(int fd, struct lock_file *index_lock, int 
flags)
+static void update_index_refresh(int flags)
 {
-   if (!index_lock) {
-   index_lock = xcalloc(1, sizeof(struct lock_file));
-   fd = hold_locked_index(index_lock, 1);
-   }
-
refresh_index(&the_index, (flags), NULL, NULL,
  _("Unstaged changes after reset:"));
-   if (write_cache(fd, active_cache, active_nr) ||
-   commit_locked_index(index_lock))
-   return error ("Could not refresh index");
-   return 0;
 }
 
 static void update_index_from_diff(struct diff_queue_struct *q,
@@ -321,9 +312,14 @@ int cmd_reset(int argc, const char **argv, const char 
*prefix)
if (pathspec) {
struct lock_file *lock = xcalloc(1, sizeof(struct lock_file));
int index_fd = hold_locked_index(lock, 1);
-   return read_from_tree(pathspec, sha1) ||
-   update_index_refresh(index_fd, lock,
-   quiet ? REFRESH_QUIET : 
REFRESH_IN_PORCELAIN);
+   if (read_from_tree(pathspec, sha1))
+   return 1;
+   update_index_refresh(
+   quiet ? REFRESH_QUIET : REFRESH_IN_PORCELAIN);
+   if (write_cache(index_fd, active_cache, active_nr) ||
+   commit_locked_index(lock))
+   return error("Could not write new index file.");
+   return 0;
}
 
/* Soft reset does not touch the index file nor the working tree
@@ -351,9 +347,15 @@ int cmd_reset(int argc, const char **argv, const char 
*prefix)
 
if (reset_type == HARD && !update_ref_status && !quiet)
print_new_head_line(commit);
-   else if (reset_type == MIXED) /* Report what has not been updated. */
-   update_index_refresh(0, NULL,
-   quiet ? REFRESH_QUIET : REFRESH_IN_PORCELAIN);
+   else if (reset_type == MIXED) { /* Report what has not been updated. */
+   struct lock_file *index_lock = xcalloc(1, sizeof(struct 
lock_file));
+   int fd = hold_locked_index(index_lock, 1);
+   update_index_refresh(
+   quiet ? REFRESH_QUIET : REFRESH_IN_PORCELAIN);
+   if (write_cache(fd, active_cache, active_nr) ||
+   commit_locked_index(index_lock))
+   error("Could not refresh index");
+   }
 
remove_branch_state();
 
-- 
1.8.1.1.454.gce43f05

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


[PATCH v2 19/19] reset [--mixed]: use diff-based reset whether or not pathspec was given

2013-01-14 Thread Martin von Zweigbergk
Thanks to b65982b (Optimize "diff-index --cached" using cache-tree,
2009-05-20), resetting with paths is much faster than resetting
without paths. Some timings for the linux-2.6 repo to illustrate this
(best of five, warm cache):

reset   reset .
real0m0.219s0m0.080s
user0m0.140s0m0.040s
sys 0m0.070s0m0.030s

These two commands should do the same thing, so instead of having the
user type the trailing " ." to get the faster do_diff_cache()-based
implementation, always use it when doing a mixed reset, with or
without paths (so "git reset $rev" would also be faster).

Timing "git reset" shows that it indeed becomes as fast as
"git reset ." after this patch.

Signed-off-by: Martin von Zweigbergk 
---
It seems like a better solution would be for unpack_trees() learn the
same tricks as do_diff_cache(). I'm leaving that a challange for the
reader :-). I did have a look a unpack_trees(), but it looked rather
overwhelming.

 builtin/reset.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/builtin/reset.c b/builtin/reset.c
index 45b01eb..921afbe 100644
--- a/builtin/reset.c
+++ b/builtin/reset.c
@@ -322,7 +322,7 @@ int cmd_reset(int argc, const char **argv, const char 
*prefix)
if (reset_type != SOFT) {
struct lock_file *lock = xcalloc(1, sizeof(struct lock_file));
int newfd = hold_locked_index(lock, 1);
-   if (pathspec) {
+   if (reset_type == MIXED) {
if (read_from_tree(pathspec, sha1))
return 1;
} else {
-- 
1.8.1.1.454.gce43f05

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


[PATCH v2 18/19] reset: allow reset on unborn branch

2013-01-14 Thread Martin von Zweigbergk
Some users seem to think, knowingly or not, that being on an unborn
branch is like having a commit with an empty tree checked out, but
when run on an unborn branch, "git reset" currently fails with:

  fatal: Failed to resolve 'HEAD' as a valid ref.

Instead of making users figure out that they should run

 git rm --cached -r .

, let's teach "git reset" without a revision argument, when on an
unborn branch, to behave as if the user asked to reset to an empty
tree. Don't take the analogy with an empty commit too far, though, but
still disallow explictly referring to HEAD in "git reset HEAD".

Signed-off-by: Martin von Zweigbergk 
---
 builtin/reset.c| 16 -
 t/t7106-reset-unborn-branch.sh | 52 ++
 2 files changed, 62 insertions(+), 6 deletions(-)
 create mode 100755 t/t7106-reset-unborn-branch.sh

diff --git a/builtin/reset.c b/builtin/reset.c
index b776867..45b01eb 100644
--- a/builtin/reset.c
+++ b/builtin/reset.c
@@ -240,7 +240,7 @@ static int update_refs(const char *rev, const unsigned char 
*sha1)
 int cmd_reset(int argc, const char **argv, const char *prefix)
 {
int reset_type = NONE, update_ref_status = 0, quiet = 0;
-   int patch_mode = 0;
+   int patch_mode = 0, unborn;
const char *rev;
unsigned char sha1[20];
const char **pathspec = NULL;
@@ -265,7 +265,11 @@ int cmd_reset(int argc, const char **argv, const char 
*prefix)
PARSE_OPT_KEEP_DASHDASH);
pathspec = parse_args(argv, prefix, &rev);
 
-   if (!pathspec) {
+   unborn = !strcmp(rev, "HEAD") && get_sha1("HEAD", sha1);
+   if (unborn) {
+   /* reset on unborn branch: treat as reset to empty tree */
+   hashcpy(sha1, EMPTY_TREE_SHA1_BIN);
+   } else if (!pathspec) {
struct commit *commit;
if (get_sha1_committish(rev, sha1))
die(_("Failed to resolve '%s' as a valid revision."), 
rev);
@@ -286,7 +290,7 @@ int cmd_reset(int argc, const char **argv, const char 
*prefix)
if (patch_mode) {
if (reset_type != NONE)
die(_("--patch is incompatible with 
--{hard,mixed,soft}"));
-   return run_add_interactive(rev, "--patch=reset", pathspec);
+   return run_add_interactive(sha1_to_hex(sha1), "--patch=reset", 
pathspec);
}
 
/* git reset tree [--] paths... can be used to
@@ -340,16 +344,16 @@ int cmd_reset(int argc, const char **argv, const char 
*prefix)
die(_("Could not write new index file."));
}
 
-   if (!pathspec) {
+   if (!pathspec && !unborn) {
/* Any resets without paths update HEAD to the head being
 * switched to, saving the previous head in ORIG_HEAD before. */
update_ref_status = update_refs(rev, sha1);
 
if (reset_type == HARD && !update_ref_status && !quiet)
print_new_head_line(lookup_commit_reference(sha1));
-
-   remove_branch_state();
}
+   if (!pathspec)
+   remove_branch_state();
 
return update_ref_status;
 }
diff --git a/t/t7106-reset-unborn-branch.sh b/t/t7106-reset-unborn-branch.sh
new file mode 100755
index 000..8062cf5
--- /dev/null
+++ b/t/t7106-reset-unborn-branch.sh
@@ -0,0 +1,52 @@
+#!/bin/sh
+
+test_description='git reset should work on unborn branch'
+. ./test-lib.sh
+
+test_expect_success 'setup' '
+   echo a >a &&
+   echo b >b
+'
+
+test_expect_success 'reset' '
+   git add a b &&
+   git reset &&
+   test "$(git ls-files)" = ""
+'
+
+test_expect_success 'reset HEAD' '
+   rm .git/index &&
+   git add a b &&
+   test_must_fail git reset HEAD
+'
+
+test_expect_success 'reset $file' '
+   rm .git/index &&
+   git add a b &&
+   git reset a &&
+   test "$(git ls-files)" = "b"
+'
+
+test_expect_success 'reset -p' '
+   rm .git/index &&
+   git add a &&
+   echo y | git reset -p &&
+   test "$(git ls-files)" = ""
+'
+
+test_expect_success 'reset --soft is a no-op' '
+   rm .git/index &&
+   git add a &&
+   git reset --soft
+   test "$(git ls-files)" = "a"
+'
+
+test_expect_success 'reset --hard' '
+   rm .git/index &&
+   git add a &&
+   git reset --hard &&
+   test "$(git ls-files)" = "" &&
+   test_path_is_missing a
+'
+
+test_done
-- 
1.8.1.1.454.gce43f05

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


[PATCH v2 17/19] reset $sha1 $pathspec: require $sha1 only to be treeish

2013-01-14 Thread Martin von Zweigbergk
Resetting with paths does not update HEAD and there is nothing else
that a commit should be needed for. Relax the argument parsing so only
a tree is required.

The sha1 is only passed to read_from_tree(), which already only
requires a tree.

The "rev" variable we pass to run_add_interactive() will resolve to a
tree. This is fine since interactive_reset only needs the parameter to
be a treeish and doesn't use it for display purposes.

Signed-off-by: Martin von Zweigbergk 
---
 builtin/reset.c  | 48 +++-
 t/t7102-reset.sh |  8 
 2 files changed, 35 insertions(+), 21 deletions(-)

diff --git a/builtin/reset.c b/builtin/reset.c
index 520c1a5..b776867 100644
--- a/builtin/reset.c
+++ b/builtin/reset.c
@@ -178,9 +178,10 @@ static const char **parse_args(const char **argv, const 
char *prefix, const char
/*
 * Possible arguments are:
 *
-* git reset [-opts]  ...
-* git reset [-opts]  -- ...
-* git reset [-opts] -- ...
+* git reset [-opts] []
+* git reset [-opts]  [...]
+* git reset [-opts]  -- [...]
+* git reset [-opts] -- [...]
 * git reset [-opts] ...
 *
 * At this point, argv points immediately after [-opts].
@@ -195,11 +196,13 @@ static const char **parse_args(const char **argv, const 
char *prefix, const char
}
/*
 * Otherwise, argv[0] could be either  or  and
-* has to be unambiguous.
+* has to be unambiguous. If there is a single argument, it
+* can not be a tree
 */
-   else if (!get_sha1_committish(argv[0], unused)) {
+   else if ((!argv[1] && !get_sha1_committish(argv[0], unused)) ||
+(argv[1] && !get_sha1_treeish(argv[0], unused))) {
/*
-* Ok, argv[0] looks like a rev; it should not
+* Ok, argv[0] looks like a commit/tree; it should not
 * be a filename.
 */
verify_non_filename(prefix, argv[0]);
@@ -241,7 +244,6 @@ int cmd_reset(int argc, const char **argv, const char 
*prefix)
const char *rev;
unsigned char sha1[20];
const char **pathspec = NULL;
-   struct commit *commit;
const struct option options[] = {
OPT__QUIET(&quiet, N_("be quiet, only report errors")),
OPT_SET_INT(0, "mixed", &reset_type,
@@ -263,19 +265,23 @@ int cmd_reset(int argc, const char **argv, const char 
*prefix)
PARSE_OPT_KEEP_DASHDASH);
pathspec = parse_args(argv, prefix, &rev);
 
-   if (get_sha1_committish(rev, sha1))
-   die(_("Failed to resolve '%s' as a valid ref."), rev);
-
-   /*
-* NOTE: As "git reset $treeish -- $path" should be usable on
-* any tree-ish, this is not strictly correct. We are not
-* moving the HEAD to any commit; we are merely resetting the
-* entries in the index to that of a treeish.
-*/
-   commit = lookup_commit_reference(sha1);
-   if (!commit)
-   die(_("Could not parse object '%s'."), rev);
-   hashcpy(sha1, commit->object.sha1);
+   if (!pathspec) {
+   struct commit *commit;
+   if (get_sha1_committish(rev, sha1))
+   die(_("Failed to resolve '%s' as a valid revision."), 
rev);
+   commit = lookup_commit_reference(sha1);
+   if (!commit)
+   die(_("Could not parse object '%s'."), rev);
+   hashcpy(sha1, commit->object.sha1);
+   } else {
+   struct tree *tree;
+   if (get_sha1_treeish(rev, sha1))
+   die(_("Failed to resolve '%s' as a valid tree."), rev);
+   tree = parse_tree_indirect(sha1);
+   if (!tree)
+   die(_("Could not parse object '%s'."), rev);
+   hashcpy(sha1, tree->object.sha1);
+   }
 
if (patch_mode) {
if (reset_type != NONE)
@@ -340,7 +346,7 @@ int cmd_reset(int argc, const char **argv, const char 
*prefix)
update_ref_status = update_refs(rev, sha1);
 
if (reset_type == HARD && !update_ref_status && !quiet)
-   print_new_head_line(commit);
+   print_new_head_line(lookup_commit_reference(sha1));
 
remove_branch_state();
}
diff --git a/t/t7102-reset.sh b/t/t7102-reset.sh
index 81b2570..1fa2a5f 100755
--- a/t/t7102-reset.sh
+++ b/t/t7102-reset.sh
@@ -497,4 +497,12 @@ test_expect_

[PATCH v2 01/19] reset $pathspec: no need to discard index

2013-01-14 Thread Martin von Zweigbergk
Since 34110cd (Make 'unpack_trees()' have a separate source and
destination index, 2008-03-06), the index no longer gets clobbered by
do_diff_cache() and we can remove the code for discarding and
re-reading it.

There are two paths to update_index_refresh() from cmd_reset(), but on
both paths, either read_cache() or read_cache_unmerged() will have
been called, so the call to read_cache() in this method is redundant
(although practically free).

This speeds up "git reset -- ." a little on the linux-2.6 repo (best
of five, warm cache):

Before  After
real0m0.093s0m0.080s
user0m0.040s0m0.020s
sys 0m0.050s0m0.050s

Signed-off-by: Martin von Zweigbergk 
---
 builtin/reset.c | 16 +---
 1 file changed, 1 insertion(+), 15 deletions(-)

diff --git a/builtin/reset.c b/builtin/reset.c
index 915cc9f..8cc7c72 100644
--- a/builtin/reset.c
+++ b/builtin/reset.c
@@ -126,9 +126,6 @@ static int update_index_refresh(int fd, struct lock_file 
*index_lock, int flags)
fd = hold_locked_index(index_lock, 1);
}
 
-   if (read_cache() < 0)
-   return error(_("Could not read index"));
-
result = refresh_index(&the_index, (flags), NULL, NULL,
   _("Unstaged changes after reset:")) ? 1 : 0;
if (write_cache(fd, active_cache, active_nr) ||
@@ -141,12 +138,6 @@ static void update_index_from_diff(struct 
diff_queue_struct *q,
struct diff_options *opt, void *data)
 {
int i;
-   int *discard_flag = data;
-
-   /* do_diff_cache() mangled the index */
-   discard_cache();
-   *discard_flag = 1;
-   read_cache();
 
for (i = 0; i < q->nr; i++) {
struct diff_filespec *one = q->queue[i]->one;
@@ -179,17 +170,15 @@ static int read_from_tree(const char *prefix, const char 
**argv,
unsigned char *tree_sha1, int refresh_flags)
 {
struct lock_file *lock = xcalloc(1, sizeof(struct lock_file));
-   int index_fd, index_was_discarded = 0;
+   int index_fd;
struct diff_options opt;
 
memset(&opt, 0, sizeof(opt));
diff_tree_setup_paths(get_pathspec(prefix, (const char **)argv), &opt);
opt.output_format = DIFF_FORMAT_CALLBACK;
opt.format_callback = update_index_from_diff;
-   opt.format_callback_data = &index_was_discarded;
 
index_fd = hold_locked_index(lock, 1);
-   index_was_discarded = 0;
read_cache();
if (do_diff_cache(tree_sha1, &opt))
return 1;
@@ -197,9 +186,6 @@ static int read_from_tree(const char *prefix, const char 
**argv,
diff_flush(&opt);
diff_tree_release_paths(&opt);
 
-   if (!index_was_discarded)
-   /* The index is still clobbered from do_diff_cache() */
-   discard_cache();
return update_index_refresh(index_fd, lock, refresh_flags);
 }
 
-- 
1.8.1.1.454.gce43f05

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


[PATCH v2 02/19] reset $pathspec: exit with code 0 if successful

2013-01-14 Thread Martin von Zweigbergk
"git reset $pathspec" currently exits with a non-zero exit code if the
worktree is dirty after resetting, which is inconsistent with reset
without pathspec, and it makes it harder to know whether the command
really failed. Change it to exit with code 0 regardless of whether the
worktree is dirty so that non-zero indicates an error.

This makes the 4 "disambiguation" test cases in t7102 clearer since
they all used to "fail", 3 of which "failed" due to changes in the
work tree. Now only the ambiguous one fails.

Signed-off-by: Martin von Zweigbergk 
---
 builtin/reset.c   |  8 +++-
 t/t2013-checkout-submodule.sh |  2 +-
 t/t7102-reset.sh  | 18 --
 3 files changed, 16 insertions(+), 12 deletions(-)

diff --git a/builtin/reset.c b/builtin/reset.c
index 8cc7c72..65413d0 100644
--- a/builtin/reset.c
+++ b/builtin/reset.c
@@ -119,19 +119,17 @@ static void print_new_head_line(struct commit *commit)
 
 static int update_index_refresh(int fd, struct lock_file *index_lock, int 
flags)
 {
-   int result;
-
if (!index_lock) {
index_lock = xcalloc(1, sizeof(struct lock_file));
fd = hold_locked_index(index_lock, 1);
}
 
-   result = refresh_index(&the_index, (flags), NULL, NULL,
-  _("Unstaged changes after reset:")) ? 1 : 0;
+   refresh_index(&the_index, (flags), NULL, NULL,
+ _("Unstaged changes after reset:"));
if (write_cache(fd, active_cache, active_nr) ||
commit_locked_index(index_lock))
return error ("Could not refresh index");
-   return result;
+   return 0;
 }
 
 static void update_index_from_diff(struct diff_queue_struct *q,
diff --git a/t/t2013-checkout-submodule.sh b/t/t2013-checkout-submodule.sh
index 70edbb3..06b18f8 100755
--- a/t/t2013-checkout-submodule.sh
+++ b/t/t2013-checkout-submodule.sh
@@ -23,7 +23,7 @@ test_expect_success '"reset " updates the index' '
git update-index --refresh &&
git diff-files --quiet &&
git diff-index --quiet --cached HEAD &&
-   test_must_fail git reset HEAD^ submodule &&
+   git reset HEAD^ submodule &&
test_must_fail git diff-files --quiet &&
git reset submodule &&
git diff-files --quiet
diff --git a/t/t7102-reset.sh b/t/t7102-reset.sh
index b096dc8..81b2570 100755
--- a/t/t7102-reset.sh
+++ b/t/t7102-reset.sh
@@ -388,7 +388,8 @@ test_expect_success 'test --mixed ' '
echo 4 > file4 &&
echo 5 > file1 &&
git add file1 file3 file4 &&
-   test_must_fail git reset HEAD -- file1 file2 file3 &&
+   git reset HEAD -- file1 file2 file3 &&
+   test_must_fail git diff --quiet &&
git diff > output &&
test_cmp output expect &&
git diff --cached > output &&
@@ -402,7 +403,8 @@ test_expect_success 'test resetting the index at give 
paths' '
>sub/file2 &&
git update-index --add sub/file1 sub/file2 &&
T=$(git write-tree) &&
-   test_must_fail git reset HEAD sub/file2 &&
+   git reset HEAD sub/file2 &&
+   test_must_fail git diff --quiet &&
U=$(git write-tree) &&
echo "$T" &&
echo "$U" &&
@@ -440,7 +442,8 @@ test_expect_success 'resetting specific path that is 
unmerged' '
echo "100644 $F3 3  file2"
} | git update-index --index-info &&
git ls-files -u &&
-   test_must_fail git reset HEAD file2 &&
+   git reset HEAD file2 &&
+   test_must_fail git diff --quiet &&
git diff-index --exit-code --cached HEAD
 '
 
@@ -449,7 +452,8 @@ test_expect_success 'disambiguation (1)' '
git reset --hard &&
>secondfile &&
git add secondfile &&
-   test_must_fail git reset secondfile &&
+   git reset secondfile &&
+   test_must_fail git diff --quiet -- secondfile &&
test -z "$(git diff --cached --name-only)" &&
test -f secondfile &&
test ! -s secondfile
@@ -474,7 +478,8 @@ test_expect_success 'disambiguation (3)' '
>secondfile &&
git add secondfile &&
rm -f secondfile &&
-   test_must_fail git reset HEAD secondfile &&
+   git reset HEAD secondfile &&
+   test_must_fail git diff --quiet &&
test -z "$(git diff --cached --name-only)" &&
test ! -f secondfile
 
@@ -486,7 +491,8 @@ test_expect_success 'disambiguation (4)' '
>secondfile &&
git add secondfile &&
rm -f secondfile &&
-   test_must_fail git reset -- secondfile &&
+   git reset -- secondfile &&
+   test_must_fail git diff --quiet &&
test -z "$(git diff --cached --name-only)" &&
test ! -f secondfile
 '
-- 
1.8.1.1.454.gce43f05

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


[PATCH v2 03/19] reset.c: pass pathspec around instead of (prefix, argv) pair

2013-01-14 Thread Martin von Zweigbergk
We use the path arguments in two places in reset.c: in
interactive_reset() and read_from_tree(). Both of these call
get_pathspec(), so we pass the (prefix, argv) pair to both
functions. Move the call to get_pathspec() out of these methods, for
two reasons: 1) One argument is simpler than two. 2) It lets us use
the (arguably clearer) "if (pathspec)" in place of "if (i < argc)".

Signed-off-by: Martin von Zweigbergk 
---
 builtin/reset.c | 27 ++-
 1 file changed, 10 insertions(+), 17 deletions(-)

diff --git a/builtin/reset.c b/builtin/reset.c
index 65413d0..045c960 100644
--- a/builtin/reset.c
+++ b/builtin/reset.c
@@ -153,26 +153,15 @@ static void update_index_from_diff(struct 
diff_queue_struct *q,
}
 }
 
-static int interactive_reset(const char *revision, const char **argv,
-const char *prefix)
-{
-   const char **pathspec = NULL;
-
-   if (*argv)
-   pathspec = get_pathspec(prefix, argv);
-
-   return run_add_interactive(revision, "--patch=reset", pathspec);
-}
-
-static int read_from_tree(const char *prefix, const char **argv,
-   unsigned char *tree_sha1, int refresh_flags)
+static int read_from_tree(const char **pathspec, unsigned char *tree_sha1,
+ int refresh_flags)
 {
struct lock_file *lock = xcalloc(1, sizeof(struct lock_file));
int index_fd;
struct diff_options opt;
 
memset(&opt, 0, sizeof(opt));
-   diff_tree_setup_paths(get_pathspec(prefix, (const char **)argv), &opt);
+   diff_tree_setup_paths(pathspec, &opt);
opt.output_format = DIFF_FORMAT_CALLBACK;
opt.format_callback = update_index_from_diff;
 
@@ -216,6 +205,7 @@ int cmd_reset(int argc, const char **argv, const char 
*prefix)
const char *rev = "HEAD";
unsigned char sha1[20], *orig = NULL, sha1_orig[20],
*old_orig = NULL, sha1_old_orig[20];
+   const char **pathspec = NULL;
struct commit *commit;
struct strbuf msg = STRBUF_INIT;
const struct option options[] = {
@@ -287,22 +277,25 @@ int cmd_reset(int argc, const char **argv, const char 
*prefix)
die(_("Could not parse object '%s'."), rev);
hashcpy(sha1, commit->object.sha1);
 
+   if (i < argc)
+   pathspec = get_pathspec(prefix, argv + i);
+
if (patch_mode) {
if (reset_type != NONE)
die(_("--patch is incompatible with 
--{hard,mixed,soft}"));
-   return interactive_reset(rev, argv + i, prefix);
+   return run_add_interactive(rev, "--patch=reset", pathspec);
}
 
/* git reset tree [--] paths... can be used to
 * load chosen paths from the tree into the index without
 * affecting the working tree nor HEAD. */
-   if (i < argc) {
+   if (pathspec) {
if (reset_type == MIXED)
warning(_("--mixed with paths is deprecated; use 'git 
reset -- ' instead."));
else if (reset_type != NONE)
die(_("Cannot do %s reset with paths."),
_(reset_type_names[reset_type]));
-   return read_from_tree(prefix, argv + i, sha1,
+   return read_from_tree(pathspec, sha1,
quiet ? REFRESH_QUIET : REFRESH_IN_PORCELAIN);
}
if (reset_type == NONE)
-- 
1.8.1.1.454.gce43f05

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


[PATCH v2 04/19] reset: don't allow "git reset -- $pathspec" in bare repo

2013-01-14 Thread Martin von Zweigbergk
Running e.g. "git reset ." in a bare repo results in an index file
being created from the HEAD commit. The differences compared to the
index are then printed as usual, but since there is no worktree, it
will appear as if all files are deleted. For example, in a bare clone
of git.git:

  Unstaged changes after reset:
  D   .gitattributes
  D   .gitignore
  D   .mailmap
  ...

This happens because the check for is_bare_repository() happens after
we branch off into read_from_tree() to reset with paths. Fix by moving
the branching point after the check.

Signed-off-by: Martin von Zweigbergk 
---
 builtin/reset.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/builtin/reset.c b/builtin/reset.c
index 045c960..664fad9 100644
--- a/builtin/reset.c
+++ b/builtin/reset.c
@@ -295,8 +295,6 @@ int cmd_reset(int argc, const char **argv, const char 
*prefix)
else if (reset_type != NONE)
die(_("Cannot do %s reset with paths."),
_(reset_type_names[reset_type]));
-   return read_from_tree(pathspec, sha1,
-   quiet ? REFRESH_QUIET : REFRESH_IN_PORCELAIN);
}
if (reset_type == NONE)
reset_type = MIXED; /* by default */
@@ -308,6 +306,10 @@ int cmd_reset(int argc, const char **argv, const char 
*prefix)
die(_("%s reset is not allowed in a bare repository"),
_(reset_type_names[reset_type]));
 
+   if (pathspec)
+   return read_from_tree(pathspec, sha1,
+   quiet ? REFRESH_QUIET : REFRESH_IN_PORCELAIN);
+
/* Soft reset does not touch the index file nor the working tree
 * at all, but requires them in a good order.  Other resets reset
 * the index file to the tree object we are switching to. */
-- 
1.8.1.1.454.gce43f05

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


  1   2   3   >