b4dc085 (pull: merge into unborn by fast-forwarding from empty tree, 2013-06-20) established git-pull's current behavior of pulling into an unborn branch by fast-forwarding the work tree from an empty tree to the merge head, then setting HEAD to the merge head. Re-implement this behavior by introducing pull_into_void() which will be called instead of run_merge() if HEAD is invalid. Helped-by: Stephen Robin <stephen.robin@xxxxxxxxx> Signed-off-by: Paul Tan <pyokagan@xxxxxxxxx> --- builtin/pull.c | 29 ++++++++++++++++++++++++++++- t/t5520-pull.sh | 4 ++-- 2 files changed, 30 insertions(+), 3 deletions(-) diff --git a/builtin/pull.c b/builtin/pull.c index 3b7029f..ba2ff01 100644 --- a/builtin/pull.c +++ b/builtin/pull.c @@ -13,6 +13,7 @@ #include "sha1-array.h" #include "remote.h" #include "dir.h" +#include "refs.h" /** * Given an option opt, where opt->value points to a char* and opt->defval is a @@ -424,6 +425,27 @@ static int run_fetch(const char *repo, const char **refspecs) } /** + * "Pulls into void" by branching off merge_head. + */ +static int pull_into_void(unsigned char merge_head[GIT_SHA1_RAWSZ], + unsigned char curr_head[GIT_SHA1_RAWSZ]) +{ + /* + * Two-way merge: we claim the index is based on an empty tree, + * and try to fast-forward to HEAD. This ensures we will not lose + * index/worktree changes that the user already made on the unborn + * branch. + */ + if (checkout_fast_forward(EMPTY_TREE_SHA1_BIN, merge_head, 0)) + return 1; + + if (update_ref("initial pull", "HEAD", merge_head, curr_head, 0, UPDATE_REFS_DIE_ON_ERR)) + return 1; + + return 0; +} + +/** * Runs git-merge, returning its exit status. */ static int run_merge(void) @@ -524,5 +546,10 @@ int cmd_pull(int argc, const char **argv, const char *prefix) if (!merge_heads.nr) die_no_merge_candidates(repo, refspecs); - return run_merge(); + if (is_null_sha1(orig_head)) { + if (merge_heads.nr > 1) + die(_("Cannot merge multiple branches into empty head.")); + return pull_into_void(*merge_heads.sha1, curr_head); + } else + return run_merge(); } diff --git a/t/t5520-pull.sh b/t/t5520-pull.sh index 3645a59..2131749 100755 --- a/t/t5520-pull.sh +++ b/t/t5520-pull.sh @@ -26,7 +26,7 @@ test_expect_success 'pulling into void' ' test_cmp file cloned/file ' -test_expect_failure 'pulling into void using master:master' ' +test_expect_success 'pulling into void using master:master' ' git init cloned-uho && ( cd cloned-uho && @@ -76,7 +76,7 @@ test_expect_success 'pulling into void does not remove new staged files' ' ) ' -test_expect_failure 'pulling into void must not create an octopus' ' +test_expect_success 'pulling into void must not create an octopus' ' git init cloned-octopus && ( cd cloned-octopus && -- 2.1.4 -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html