Commit graph

24 commits

Author SHA1 Message Date
Stephen Haberman 66713ef3b0 pull: allow pull to preserve merges when rebasing
If a user is working on master, and has merged in their feature branch, but now
has to "git pull" because master moved, with pull.rebase their feature branch
will be flattened into master.

This is because "git pull" currently does not know about rebase's preserve
merges flag, which would avoid this behavior, as it would instead replay just
the merge commit of the feature branch onto the new master, and not replay each
individual commit in the feature branch.

Add a --rebase=preserve option, which will pass along --preserve-merges to
rebase.

Also add 'preserve' to the allowed values for the pull.rebase config setting.

Signed-off-by: Stephen Haberman <stephen@exigencecorp.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-09-04 12:45:48 -07:00
Junio C Hamano 833cd7fc9f Merge branch 'jk/pull-into-dirty-unborn'
"git pull" into nothing trashed "local changes" that were in the
index, and this avoids it.

* jk/pull-into-dirty-unborn:
  pull: merge into unborn by fast-forwarding from empty tree
  pull: update unborn branch tip after index
2013-06-27 14:29:52 -07:00
Thomas Rast b4dc085a8d pull: merge into unborn by fast-forwarding from empty tree
The logic for pulling into an unborn branch was originally
designed to be used on a newly-initialized repository
(d09e79c, git-pull: allow pulling into an empty repository,
2006-11-16).  It thus did not initially deal with
uncommitted changes in the unborn branch.  The case of an
_unstaged_ untracked file was fixed by 4b3ffe5 (pull: do not
clobber untracked files on initial pull, 2011-03-25).
However, it still clobbered existing staged files, both when
the file exists in the merged commit (it will be
overwritten), and when it does not (it will be deleted).

We fix this by doing a two-way merge, where the "current"
side of the merge is an empty tree, and the "target" side is
HEAD (already updated to FETCH_HEAD at this point).  This
amounts to claiming that all work in the index was done vs.
an empty tree, and thus all content of the index is
precious.

Note that this use of read-tree just gives us protection
against overwriting index and working tree changes. It will
not actually result in a 3-way merge conflict in the index.
This is fine, as this is a rare situation, and the conflict
would not be interesting anyway (it must, by definition, be
an add/add conflict with the whole content conflicting). And
it makes it simpler for the user to recover, as they have no
HEAD to "git reset" back to.

Reported-by: Stefan Schüßler <mail@stefanschuessler.de>
Signed-off-by: Thomas Rast <trast@inf.ethz.ch>
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-06-20 15:51:35 -07:00
Ramkumar Ramachandra 790f282737 t5520: use test_config to set/unset git config variables (leftover bits)
Configuration from test_config does not last beyond the end of the
current test assertion, making each test easier to think about in
isolation.

Signed-off-by: Ramkumar Ramachandra <artagnon@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-03-28 08:16:07 -07:00
Yann Droneaud 9d6aa64dc3 t5520: use test_config to set/unset git config variables
Instead of using construct such as:
    test_when_finished "git config --unset <key>"
    git config <key> <value>
uses
    test_config <key> <value>
The latter takes care of removing <key> at the end of the test.

Signed-off-by: Yann Droneaud <ydroneaud@opteya.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-03-25 08:50:53 -07:00
Ævar Arnfjörð Bjarmason 6b37dff17f pull: introduce a pull.rebase option to enable --rebase
Currently we either need to set branch.<name>.rebase for existing
branches if we'd like "git pull" to mean "git pull --rebase", or have
the forethought of setting "branch.autosetuprebase" before we create
the branch.

Introduce a "pull.rebase" option to globally configure "git pull" to
mean "git pull --rebase" for any branch.

This option will be considered at a lower priority than
branch.<name>.rebase, i.e. we could set pull.rebase=true and
branch.<name>.rebase=false and the latter configuration option would
win.

Reviewed-by: Sverre Rabbelier <srabbelier@gmail.com>
Reviewed-by: Fernando Vezzosi <buccia@repnz.net>
Reviewed-by: Eric Herman <eric@freesa.org>
Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
Liked-by: Johannes Schindelin <Johannes.Schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-11-07 08:43:11 -08:00
Jeff King 4b3ffe5184 pull: do not clobber untracked files on initial pull
For a pull into an unborn branch, we do not use "git merge"
at all. Instead, we call read-tree directly. However, we
used the --reset parameter instead of "-m", which turns off
the safety features.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-03-25 14:16:27 -07:00
Martin von Zweigbergk fe249b4219 Use reflog in 'pull --rebase . foo'
Since c85c792 (pull --rebase: be cleverer with rebased upstream
branches, 2008-01-26), "git pull --rebase" has used the reflog to try to
rebase from the old upstream onto the new upstream.

Make this work if the local repository is explicitly passed on the
command line as in 'git pull --rebase . foo'.

Signed-off-by: Martin von Zweigbergk <martin.von.zweigbergk@gmail.com>
Acked-by: Santi Béjar <santi@agolina.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2010-11-29 15:06:40 -08:00
Junio C Hamano d25c72f7da Merge branch 'en/rebase-against-rebase-fix'
* en/rebase-against-rebase-fix:
  pull --rebase: Avoid spurious conflicts and reapplying unnecessary patches
  t5520-pull: Add testcases showing spurious conflicts from git pull --rebase
2010-08-21 23:27:29 -07:00
Elijah Newren cf65426de6 pull --rebase: Avoid spurious conflicts and reapplying unnecessary patches
Prior to c85c792 (pull --rebase: be cleverer with rebased upstream
branches, 2008-01-26), pull --rebase would run

  git rebase $merge_head

which resulted in a call to

  git format-patch ... --ignore-if-in-upstream $merge_head..$cur_branch

This resulted in patches from $merge_head..$cur_branch being applied, as
long as they did not already exist in $cur_branch..$merge_head.

Unfortunately, when upstream is rebased, $merge_head..$cur_branch also
refers to "old" commits that have already been rebased upstream, meaning
that many patches that were already fixed upstream would be reapplied.
This could result in many spurious conflicts, as well as reintroduce
patches that were intentionally dropped upstream.

So the algorithm was changed in c85c792 (pull --rebase: be cleverer with
rebased upstream branches, 2008-01-26) and d44e712 (pull: support rebased
upstream + fetch + pull --rebase, 2009-07-19).  Defining $old_remote_ref to
be the most recent entry in the reflog for @{upstream} that is an ancestor
of $cur_branch, pull --rebase was changed to run

  git rebase --onto $merge_head $old_remote_ref

which results in a call to

  git format-patch ... --ignore-if-in-upstream $old_remote_ref..$cur_branch

The whole point of this change was to reduce the number of commits being
reapplied, by avoiding commits that upstream already has or had.

In the rebased upstream case, this change achieved that purpose.  It is
worth noting, though, that since $old_remote_ref is always an ancestor of
$cur_branch (by its definition), format-patch will not know what upstream
is and thus will not be able to determine if any patches are already
upstream; they will all be reapplied.

In the non-rebased upstream case, this new form is usually the same as the
original code but in some cases $old_remote_ref can be an ancestor of

   $(git merge-base $merge_head $cur_branch)

meaning that instead of avoiding reapplying commits that upstream already
has, it actually includes more such commits.  Combined with the fact that
format-patch can no longer detect commits that are already upstream (since
it is no longer told what upstream is), results in lots of confusion for
users (e.g. "git is giving me lots of conflicts in stuff I didn't even
change since my last push.")

Cases where additional commits could be reapplied include forking from a
commit other than the tracking branch, or amending/rebasing after pushing.
Cases where the inability to detect upstreamed commits cause problems
include independent discovery of a fix and having your patches get
upstreamed by some alternative route (e.g. pulling your changes to a third
machine, pushing from there, and then going back to your original machine
and trying to pull --rebase).

Fix the non-rebased upstream case by ignoring $old_remote_ref whenever it
is contained in $(git merge-base $merge_head $cur_branch).  This should
have no affect on the rebased upstream case.

Acked-by: Santi Béjar <santi@agolina.net>
Signed-off-by: Elijah Newren <newren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2010-08-12 21:23:23 -07:00
Elijah Newren 3cee92369e t5520-pull: Add testcases showing spurious conflicts from git pull --rebase
Signed-off-by: Elijah Newren <newren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2010-08-12 21:22:55 -07:00
Gary V. Vaughan 4fdf71be1c tests: use "test_cmp", not "diff", when verifying the result
In tests, call test_cmp rather than raw diff where possible (i.e. if
the output does not go to a pipe), to allow the use of, say, 'cmp'
when the default 'diff -u' is not compatible with a vendor diff.

When that is not possible, use $DIFF, as set in GIT-BUILD-OPTIONS.

Signed-off-by: Gary V. Vaughan <gary@thewrittenword.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2010-05-31 16:59:27 -07:00
Jeff King 19a7fcbf16 allow pull --rebase on branch yet to be born
When doing a "pull --rebase", we check to make sure that the index and
working tree are clean. The index-clean check compares the index against
HEAD. The test erroneously reports dirtiness if we don't have a HEAD yet.

In such an "unborn branch" case, by definition, a non-empty index won't
be based on whatever we are pulling down from the remote, and will lose
the local change.  Just check if $GIT_DIR/index exists and error out.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-08-12 15:50:09 -07:00
Santi Béjar d44e71261f pull: support rebased upstream + fetch + pull --rebase
You cannot do a "git pull --rebase" with a rebased upstream, if you have
already run "git fetch".  Try to behave as if the "git fetch" was not run.

In other words, find the fork point of the current branch, where
the tip of upstream branch used to be, and use it as the upstream
parameter of "git rebase".

This patch computes the fork point by walking the reflog to find the first
commit which is an ancestor of the current branch.  Maybe there are
smarter ways to compute it, but this is a straight forward implementation.

Signed-off-by: Santi Béjar <santi@agolina.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-07-19 10:29:38 -07:00
Santi Béjar a418441b4e t5520-pull: Test for rebased upstream + fetch + pull --rebase
If your upstream has rebased you can do:

git pull --rebase

but only if you haven't fetch before.

Mark this case as test_expect_failure, in a later patch it will be
changed to test_expect_success.

Signed-off-by: Santi Béjar <santi@agolina.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-07-19 10:28:50 -07:00
Santi Béjar e9460a66e0 parse-remote: support default reflist in get_remote_merge_branch
Expand get_remote_merge_branch to compute the tracking branch to merge
when called without arguments (or only the remote name). This allows
"git pull --rebase" without arguments (default upstream branch) to
work with a rebased upstream. With explicit arguments it already worked.

Also add a test to check for this case.

Signed-off-by: Santi Béjar <santi@agolina.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-06-11 19:50:34 -07:00
Junio C Hamano b0ad11ea16 pull: allow "git pull origin $something:$current_branch" into an unborn branch
Some misguided documents floating on the Net suggest this sequence:

    mkdir newdir && cd newdir
    git init
    git remote add origin $url
    git pull origin master:master

"git pull" has known about misguided "pull" that lets the underlying fetch
update the current branch for a long time.  It also has known about
"git pull origin master" into a branch yet to be born.

These two workarounds however were not aware of the existence of each
other and did not work well together.  This fixes it.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
2008-10-17 11:26:20 -07:00
Johannes Schindelin f9189cf8f2 pull --rebase: exit early when the working directory is dirty
When rebasing fails during "pull --rebase", you cannot just clean up the
working directory and call "pull --rebase" again, since the remote branch
was already fetched.

Therefore, die early when the working directory is dirty.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2008-05-22 23:05:11 -07:00
Johannes Schindelin c85c79279d pull --rebase: be cleverer with rebased upstream branches
When the upstream branch is tracked, we can detect if that branch
was rebased since it was last fetched.  Teach git to use that
information to rebase from the old remote head onto the new remote head.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2008-01-26 18:24:24 -08:00
Johannes Schindelin cd67e4d46b Teach 'git pull' about --rebase
When calling 'git pull' with the '--rebase' option, it performs a
fetch + rebase instead of a fetch + merge.

This behavior is more desirable than fetch + pull when a topic branch
is ready to be submitted and needs to be update.

fetch + rebase might also be considered a better workflow with shared
repositories in any case, or for contributors to a centrally managed
repository, such as WINE's.

As a convenience, you can set the default behavior for a branch by
defining the config variable branch.<name>.rebase, which is
interpreted as a bool.  This setting can be overridden on the command
line by --rebase and --no-rebase.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2007-11-28 17:32:23 -08:00
Junio C Hamano a6080a0a44 War on whitespace
This uses "git-apply --whitespace=strip" to fix whitespace errors that have
crept in to our source files over time.  There are a few files that need
to have trailing whitespaces (most notably, test vectors).  The results
still passes the test, and build result in Documentation/ area is unchanged.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
2007-06-07 00:04:01 -07:00
Paolo Bonzini 9debc3241b git-fetch, git-branch: Support local --track via a special remote '.'
This patch adds support for a dummy remote '.' to avoid having
to declare a fake remote like

        [remote "local"]
                url = .
                fetch = refs/heads/*:refs/heads/*

Such a builtin remote simplifies the operation of "git-fetch",
which will populate FETCH_HEAD but will not pretend that two
repositories are in use, will not create a thin pack, and will
not perform any useless remapping of names.  The speed
improvement is around 20%, and it should improve more if
"git-fetch" is converted to a builtin.

To this end, git-parse-remote is grown with a new kind of
remote, 'builtin'.  In git-fetch.sh, we treat the builtin remote
specially in that it needs no pack/store operations.  In fact,
doing git-fetch on a builtin remote will simply populate
FETCH_HEAD appropriately.

The patch also improves of the --track/--no-track support,
extending it so that branch.<name>.remote items referring '.'
can be created.  Finally, it fixes a typo in git-checkout.sh.

Signed-off-by: Paolo Bonzini  <bonzini@gnu.org>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2007-03-16 02:10:12 -07:00
Nicolas Pitre 5c94f87e6b use 'init' instead of 'init-db' for shipped docs and tools
While 'init-db' still is and probably will always remain a valid git
command for obvious backward compatibility reasons, it would be a good
idea to move shipped tools and docs to using 'init' instead.

Signed-off-by: Nicolas Pitre <nico@cam.org>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2007-01-12 13:36:16 -08:00
Linus Torvalds d09e79cb1c git-pull: allow pulling into an empty repository
We used to complain that we cannot merge anything we fetched
with a local branch that does not exist yet.  Just treat the
case as a natural extension of fast forwarding and make the
local branch'es tip point at the same commit we just fetched.
After all an empty repository without an initial commit is an
ancestor of any commit.

[jc: I added a trivial test.  We've become sloppy but we should
 stick to the discipline of covering new behaviour with new
 tests. ]

Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-11-16 23:45:48 -08:00