Re: [BUG] rebase no longer omits local commits

2014-07-07 Thread Junio C Hamano
John Keeping j...@keeping.me.uk writes:

 Perhaps we shuld do something like this (which passes the test suite):

 -- 8 --
 diff --git a/git-rebase.sh b/git-rebase.sh
 index 06c810b..0c6c5d3 100755
 --- a/git-rebase.sh
 +++ b/git-rebase.sh
 @@ -544,7 +544,8 @@ if test $fork_point = t
  then
   new_upstream=$(git merge-base --fork-point $upstream_name \
   ${switch_to:-HEAD})
 - if test -n $new_upstream
 + if test -n $new_upstream 
 +! git merge-base --is-ancestor $new_upstream $upstream_name
   then
   upstream=$new_upstream
   fi
 -- 8 --

 Since the intent of `--fork-point` is to find the best starting point
 for the $upstream...$orig_head range, if the fork point is behind the
 new location of the upstream then should we leave the upstream as it
 was?

Probably; but the check to avoid giving worse fork-point should be
in the implementation of merge-base --fork-point itself, so that
we do not have to do the above to both rebase and pull --rebase,
no?

 I haven't thought through this completely, but it seems like we should
 be doing a check like the above, at least when we're in
 $fork_point=auto mode.
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [BUG] rebase no longer omits local commits

2014-07-07 Thread John Keeping
On Mon, Jul 07, 2014 at 10:56:23AM -0700, Junio C Hamano wrote:
 John Keeping j...@keeping.me.uk writes:
 
  Perhaps we shuld do something like this (which passes the test suite):
 
  -- 8 --
  diff --git a/git-rebase.sh b/git-rebase.sh
  index 06c810b..0c6c5d3 100755
  --- a/git-rebase.sh
  +++ b/git-rebase.sh
  @@ -544,7 +544,8 @@ if test $fork_point = t
   then
  new_upstream=$(git merge-base --fork-point $upstream_name \
  ${switch_to:-HEAD})
  -   if test -n $new_upstream
  +   if test -n $new_upstream 
  +  ! git merge-base --is-ancestor $new_upstream $upstream_name
  then
  upstream=$new_upstream
  fi
  -- 8 --
 
  Since the intent of `--fork-point` is to find the best starting point
  for the $upstream...$orig_head range, if the fork point is behind the
  new location of the upstream then should we leave the upstream as it
  was?
 
 Probably; but the check to avoid giving worse fork-point should be
 in the implementation of merge-base --fork-point itself, so that
 we do not have to do the above to both rebase and pull --rebase,
 no?

I don't think so, since in that case we're not actually finding the fork
point as defined in the documentation, we're finding the upstream rebase
wants.

Having played with this a bit, I think we shouldn't be replacing the
upstream with the fork point but should instead add the fork point as an
additional negative ref:

$upstream...$orig_head ^$fork_point

Here's a script that creates a repository showing this:

-- 8 --
#!/bin/sh
git init rebase-test 
cd rebase-test 
echo one file 
git add file 
git commit -m one 
echo frist file2 
git add file2 
git commit -m first 
git branch --track dev 
echo first file2 
git commit -a --amend --no-edit 
echo two file 
git commit -a -m two 
echo three file 
git commit -a -m three 
echo second file2 
git commit -a -m second 
git checkout dev 
git cherry-pick -2 master 
echo four file 
git commit -a -m four 
printf '\nWithout fork point (old behaviour)\n' 
git rev-list --oneline --cherry @{u}... 
printf '\nFork point as upstream (current behaviour)\n' 
git rev-list --oneline --cherry $(git merge-base --fork-point master HEAD)... 
printf '\nWith fork point\n' 
git rev-list --oneline --cherry @{u}... ^$(git merge-base --fork-point master 
HEAD)
-- 8 --

In this case the rebase should be clean since the only applicable patch
changes three to four in file, but the current rebase code fails
both with `--fork-point` and with `--no-fork-point`.

With `--fork-point` we try to apply two and three which have already
been cherry-picked across (as Ted originally reported) and with
`--no-fork-point`, we try to apply first which conflicts because we
have the version prior to it being fixed up on master.

I hacked up git-rebase to test this and the change to use the fork point
as in the last line of the script above does indeed make the rebase go
through cleanly, but I have not yet looked at how to cleanly patch in
that behaviour.

I haven't tested git-pull, but it looks like it has always (since 2009)
behaved in the way `git rebase --fork-point` does now, failing to detect
cherry-picked commits that are now in the 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


[BUG] rebase no longer omits local commits

2014-07-03 Thread Ted Felix
Starting with git 1.9.0, rebase no longer omits local commits that 
appear in both the upstream and local branches.


I've bisected this down to commit bb3f458: rebase: fix fork-point with 
zero arguments.  The attached script reproduces the problem.  Reverting 
the aforementioned commit fixes the problem.


A failed run of this script will result in conflicts.  A successful run 
against master with bb3f458 reverted ends as follows:


From /tmp/rebase-issue/maint
   fe401cd..955af04  master - origin/master
fatal: Not a valid object name: ''
First, rewinding head to replay your work on top of it...
Applying: Third change

(I'm not sure if that fatal: Not a valid object name: '' is of any 
concern.  It started appearing for me at some point during the bisect.)


Let me know if there's more I can do to help.

#!/bin/bash

# git-rebase is supposed to drop commits that it finds in both the 
# local and upstream branches.  As of 1.9.0, this isn't happening.
# This script reproduces the problem.

# I've bisected the issue down to commit bb3f458.  Reverting that commit
# solves the problem.

# Run this in a directory where you have create privs.
# At the end, if there are conflicts, then the test has failed.

# Create a repo.
mkdir rebase-issue
cd rebase-issue
mkdir maint
cd maint
git init

# Create a README file and put some text in it
echo Hi there! README
git add README
git commit -a -m Initial commit

# Clone the repo for dev
cd ..
git clone maint dev

# Dev makes *two* changes to the *same* area.
cd dev
# edit something, make some typos
echo Freekwently Mispeled Werdz README
git commit -a -m First change
# edit same thing, fix those typos
echo Frequently Misspelled Words README
git commit -a -m Second change

# Create patches to send to maintainer...
git format-patch -M origin/master
mv *.patch ../maint

# Add a third change that should make it through for completeness.
echo Frequently Misspelled Words version 2 README
git commit -a -m Third change

# We have to sleep (to make sure the times do not match?).
# If we don't, this script will succeed on fast machines.
# This can probably be reduced to 2 which should guarantee that
# the seconds will turn over on the clock.
echo
echo Waiting 5 seconds to make sure apply time is different from patch time...
sleep 5

echo
echo Maint applies patches...
cd ../maint
git am -3 *.patch

echo
echo Dev does the fetch/rebase...
cd ../dev
git fetch
git rebase

echo
git --version



Re: [BUG] rebase no longer omits local commits

2014-07-03 Thread John Keeping
On Thu, Jul 03, 2014 at 11:14:26AM -0400, Ted Felix wrote:
 Starting with git 1.9.0, rebase no longer omits local commits that 
 appear in both the upstream and local branches.
 
 I've bisected this down to commit bb3f458: rebase: fix fork-point with 
 zero arguments.  The attached script reproduces the problem.  Reverting 
 the aforementioned commit fixes the problem.
 
 A failed run of this script will result in conflicts.  A successful run 
 against master with bb3f458 reverted ends as follows:
 
  From /tmp/rebase-issue/maint
 fe401cd..955af04  master - origin/master
 fatal: Not a valid object name: ''
 First, rewinding head to replay your work on top of it...
 Applying: Third change
 
 (I'm not sure if that fatal: Not a valid object name: '' is of any 
 concern.  It started appearing for me at some point during the bisect.)

It is the problem that bb3f458 fixes.  The change in behaviour is
actually introduced by ad8261d (rebase: use reflog to find common base
with upstream).

In your example, I think this is working as designed.  You can restore
the previous behaviour either with `git rebase --no-fork-point` or with
`git rebase @{u}`.

The change is designed to help users recover from an upstream rebase, as
described in the DISCUSSION ON FORK-POINT MODE section of
git-merge-base(1) and makes `git rebase` match the behaviour of
`git pull --rebase` so that:

git fetch 
git rebase

really is equivalent to:

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


Re: [BUG] rebase no longer omits local commits

2014-07-03 Thread John Keeping
On Thu, Jul 03, 2014 at 08:09:17PM +0100, John Keeping wrote:
 On Thu, Jul 03, 2014 at 11:14:26AM -0400, Ted Felix wrote:
  Starting with git 1.9.0, rebase no longer omits local commits that 
  appear in both the upstream and local branches.
 
 It is the problem that bb3f458 fixes.  The change in behaviour is
 actually introduced by ad8261d (rebase: use reflog to find common base
 with upstream).
 
 In your example, I think this is working as designed.  You can restore
 the previous behaviour either with `git rebase --no-fork-point` or with
 `git rebase @{u}`.
 
 The change is designed to help users recover from an upstream rebase, as
 described in the DISCUSSION ON FORK-POINT MODE section of
 git-merge-base(1).

Having thought about this a bit more, I think the case you've identified
is an unexpected side effect of that commit.

Perhaps we shuld do something like this (which passes the test suite):

-- 8 --
diff --git a/git-rebase.sh b/git-rebase.sh
index 06c810b..0c6c5d3 100755
--- a/git-rebase.sh
+++ b/git-rebase.sh
@@ -544,7 +544,8 @@ if test $fork_point = t
 then
new_upstream=$(git merge-base --fork-point $upstream_name \
${switch_to:-HEAD})
-   if test -n $new_upstream
+   if test -n $new_upstream 
+  ! git merge-base --is-ancestor $new_upstream $upstream_name
then
upstream=$new_upstream
fi
-- 8 --

Since the intent of `--fork-point` is to find the best starting point
for the $upstream...$orig_head range, if the fork point is behind the
new location of the upstream then should we leave the upstream as it
was?

I haven't thought through this completely, but it seems like we should
be doing a check like the above, at least when we're in
$fork_point=auto mode.
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html