2015-06-14 10:41:51 +02:00
|
|
|
/*
|
|
|
|
* Builtin "git pull"
|
|
|
|
*
|
|
|
|
* Based on git-pull.sh by Junio C Hamano
|
|
|
|
*
|
|
|
|
* Fetch one or more remote refs and merge it/them into the current HEAD.
|
|
|
|
*/
|
|
|
|
#include "cache.h"
|
2017-06-14 20:07:36 +02:00
|
|
|
#include "config.h"
|
2015-06-14 10:41:51 +02:00
|
|
|
#include "builtin.h"
|
|
|
|
#include "parse-options.h"
|
|
|
|
#include "exec_cmd.h"
|
2015-06-14 10:41:52 +02:00
|
|
|
#include "run-command.h"
|
pull: error on no merge candidates
Commit a8c9bef (pull: improve advice for unconfigured error case,
2009-10-05) fully established the current advices given by git-pull for
the different cases where git-fetch will not have anything marked for
merge:
1. We fetched from a specific remote, and a refspec was given, but it
ended up not fetching anything. This is usually because the user
provided a wildcard refspec which had no matches on the remote end.
2. We fetched from a non-default remote, but didn't specify a branch to
merge. We can't use the configured one because it applies to the
default remote, and thus the user must specify the branches to merge.
3. We fetched from the branch's or repo's default remote, but:
a. We are not on a branch, so there will never be a configured branch
to merge with.
b. We are on a branch, but there is no configured branch to merge
with.
4. We fetched from the branch's or repo's default remote, but the
configured branch to merge didn't get fetched (either it doesn't
exist, or wasn't part of the configured fetch refspec)
Re-implement the above behavior by implementing get_merge_heads() to
parse the heads in FETCH_HEAD for merging, and implementing
die_no_merge_candidates(), which will be called when FETCH_HEAD has no
heads for merging.
Helped-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Helped-by: Junio C Hamano <gitster@pobox.com>
Signed-off-by: Paul Tan <pyokagan@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2015-06-18 12:54:02 +02:00
|
|
|
#include "sha1-array.h"
|
|
|
|
#include "remote.h"
|
2015-06-18 12:54:04 +02:00
|
|
|
#include "dir.h"
|
2015-06-18 12:54:06 +02:00
|
|
|
#include "refs.h"
|
2015-06-18 12:54:10 +02:00
|
|
|
#include "revision.h"
|
pull: optionally rebase submodules (remote submodule changes only)
Teach pull to optionally update submodules when '--recurse-submodules'
is provided. This will teach pull to run 'submodule update --rebase'
when the '--recurse-submodules' and '--rebase' flags are given under
specific circumstances.
On a rebase workflow:
=====================
1. Both sides change the submodule
------------------------------
Let's assume the following history in a submodule:
H---I---J---K---L local branch
\
M---N---O---P remote branch
and the following in the superproject (recorded submodule in parens):
A(H)---B(I)---F(K)---G(L) local branch
\
C(N)---D(N)---E(P) remote branch
In an ideal world this would rebase the submodule and rewrite
the submodule pointers that the superproject points at such that
the superproject looks like
A(H)---B(I) F(K')---G(L') rebased branch
\ /
C(N)---D(N)---E(P) remote branch
and the submodule as:
J---K---L (old dangeling tip)
/
H---I J'---K'---L' rebased branch
\ /
M---N---O---P remote branch
And if a conflict arises in the submodule the superproject rebase
would stop at that commit at which the submodule conflict occurs.
Currently a "pull --rebase" in the superproject produces
a merge conflict as the submodule pointer changes are
conflicting and cannot be resolved.
2. Local submodule changes only
-----------------------
Assuming histories as above, except that the remote branch
would not contain submodule changes, then a result as
A(H)---B(I) F(K)---G(L) rebased branch
\ /
C(I)---D(I)---E(I) remote branch
is desire-able. This is what currently happens in rebase.
If the recursive flag is given, the ideal git would
produce a superproject as:
A(H)---B(I) F(K')---G(L') rebased branch (incl. sub rebase!)
\ /
C(I)---D(I)---E(I) remote branch
and the submodule as:
J---K---L (old dangeling tip)
/
H---I J'---K'---L' locally rebased branch
\ /
M---N---O---P advanced branch
This patch doesn't address this issue, however
a test is added that this fails up front.
3. Remote submodule changes only
----------------------
Assuming histories as in (1) except that the local superproject branch
would not have touched the submodule the rebase already works out in the
superproject with no conflicts:
A(H)---B(I) F(P)---G(P) rebased branch (no sub changes)
\ /
C(N)---D(N)---E(P) remote branch
The recurse flag as presented in this patch would additionally
update the submodule as:
H---I J'---K'---L' rebased branch
\ /
M---N---O---P remote branch
As neither J, K, L nor J', K', L' are referred to from the superproject,
no rewriting of the superproject commits is required.
Conclusion for 'pull --rebase --recursive'
-----------------------------------------
If there are no local superproject changes it is sufficient to call
"submodule update --rebase" as this produces the desired results. In case
of conflicts, the behavior is the same as in 'submodule update --recursive'
which is assumed to be sane.
This patch implements (3) only.
On a merge workflow:
====================
We'll start off with the same underlying DAG as in (1) in the rebase
workflow. So in an ideal world a 'pull --merge --recursive' would
produce this:
H---I---J---K---L----X
\ /
M---N---O---P
with X as the new merge-commit in the submodule and the superproject
as:
A(H)---B(I)---F(K)---G(L)---Y(X)
\ /
C(N)---D(N)---E(P)
However modifying the submodules on the fly is not supported in git-merge
such that Y(X) is not easy to produce in a single patch. In fact git-merge
doesn't know about submodules at all.
However when at least one side does not contain commits touching the
submodule at all, then we do not need to perform the merge for the
submodule but a fast-forward can be done via checking out either L or P
in the submodule. This strategy is implemented in 68d03e4a6e (Implement
automatic fast-forward merge for submodules, 2010-07-07) already, so
to align with the rebase behavior we need to also update the worktree
of the submodule.
Signed-off-by: Brandon Williams <bmwill@google.com>
Signed-off-by: Stefan Beller <sbeller@google.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-06-23 21:13:02 +02:00
|
|
|
#include "submodule.h"
|
|
|
|
#include "submodule-config.h"
|
2015-08-25 23:57:09 +02:00
|
|
|
#include "tempfile.h"
|
2015-06-18 12:54:10 +02:00
|
|
|
#include "lockfile.h"
|
2016-10-07 18:08:38 +02:00
|
|
|
#include "wt-status.h"
|
2015-06-14 10:41:51 +02:00
|
|
|
|
pull: teach git pull about --rebase
Since cd67e4d (Teach 'git pull' about --rebase, 2007-11-28), if the
--rebase option is set, git-rebase is run instead of git-merge.
Re-implement this by introducing run_rebase(), which is called instead
of run_merge() if opt_rebase is a true value.
Since c85c792 (pull --rebase: be cleverer with rebased upstream
branches, 2008-01-26), git-pull handles the case where the upstream
branch was rebased since it was last fetched. The fork point (old remote
ref) of the branch from the upstream branch is calculated before fetch,
and then rebased from onto the new remote head (merge_head) after fetch.
Re-implement this by introducing get_merge_branch_2() and
get_merge_branch_1() to find the upstream branch for the
specified/current branch, and get_rebase_fork_point() which will find
the fork point between the upstream branch and current branch.
However, the above change created a problem where git-rebase cannot
detect commits that are already upstream, and thus may result in
unnecessary conflicts. cf65426 (pull --rebase: Avoid spurious conflicts
and reapplying unnecessary patches, 2010-08-12) fixes this by ignoring
the above old remote ref if it is contained within the merge base of the
merge head and the current branch.
This is re-implemented in run_rebase() where fork_point is not used if
it is the merge base returned by get_octopus_merge_base().
Helped-by: Stefan Beller <sbeller@google.com>
Helped-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Paul Tan <pyokagan@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2015-06-18 12:54:08 +02:00
|
|
|
enum rebase_type {
|
|
|
|
REBASE_INVALID = -1,
|
|
|
|
REBASE_FALSE = 0,
|
|
|
|
REBASE_TRUE,
|
2016-01-13 13:17:15 +01:00
|
|
|
REBASE_PRESERVE,
|
|
|
|
REBASE_INTERACTIVE
|
pull: teach git pull about --rebase
Since cd67e4d (Teach 'git pull' about --rebase, 2007-11-28), if the
--rebase option is set, git-rebase is run instead of git-merge.
Re-implement this by introducing run_rebase(), which is called instead
of run_merge() if opt_rebase is a true value.
Since c85c792 (pull --rebase: be cleverer with rebased upstream
branches, 2008-01-26), git-pull handles the case where the upstream
branch was rebased since it was last fetched. The fork point (old remote
ref) of the branch from the upstream branch is calculated before fetch,
and then rebased from onto the new remote head (merge_head) after fetch.
Re-implement this by introducing get_merge_branch_2() and
get_merge_branch_1() to find the upstream branch for the
specified/current branch, and get_rebase_fork_point() which will find
the fork point between the upstream branch and current branch.
However, the above change created a problem where git-rebase cannot
detect commits that are already upstream, and thus may result in
unnecessary conflicts. cf65426 (pull --rebase: Avoid spurious conflicts
and reapplying unnecessary patches, 2010-08-12) fixes this by ignoring
the above old remote ref if it is contained within the merge base of the
merge head and the current branch.
This is re-implemented in run_rebase() where fork_point is not used if
it is the merge base returned by get_octopus_merge_base().
Helped-by: Stefan Beller <sbeller@google.com>
Helped-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Paul Tan <pyokagan@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2015-06-18 12:54:08 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Parses the value of --rebase. If value is a false value, returns
|
|
|
|
* REBASE_FALSE. If value is a true value, returns REBASE_TRUE. If value is
|
|
|
|
* "preserve", returns REBASE_PRESERVE. If value is a invalid value, dies with
|
|
|
|
* a fatal error if fatal is true, otherwise returns REBASE_INVALID.
|
|
|
|
*/
|
|
|
|
static enum rebase_type parse_config_rebase(const char *key, const char *value,
|
|
|
|
int fatal)
|
|
|
|
{
|
2017-08-07 20:20:49 +02:00
|
|
|
int v = git_parse_maybe_bool(value);
|
pull: teach git pull about --rebase
Since cd67e4d (Teach 'git pull' about --rebase, 2007-11-28), if the
--rebase option is set, git-rebase is run instead of git-merge.
Re-implement this by introducing run_rebase(), which is called instead
of run_merge() if opt_rebase is a true value.
Since c85c792 (pull --rebase: be cleverer with rebased upstream
branches, 2008-01-26), git-pull handles the case where the upstream
branch was rebased since it was last fetched. The fork point (old remote
ref) of the branch from the upstream branch is calculated before fetch,
and then rebased from onto the new remote head (merge_head) after fetch.
Re-implement this by introducing get_merge_branch_2() and
get_merge_branch_1() to find the upstream branch for the
specified/current branch, and get_rebase_fork_point() which will find
the fork point between the upstream branch and current branch.
However, the above change created a problem where git-rebase cannot
detect commits that are already upstream, and thus may result in
unnecessary conflicts. cf65426 (pull --rebase: Avoid spurious conflicts
and reapplying unnecessary patches, 2010-08-12) fixes this by ignoring
the above old remote ref if it is contained within the merge base of the
merge head and the current branch.
This is re-implemented in run_rebase() where fork_point is not used if
it is the merge base returned by get_octopus_merge_base().
Helped-by: Stefan Beller <sbeller@google.com>
Helped-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Paul Tan <pyokagan@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2015-06-18 12:54:08 +02:00
|
|
|
|
|
|
|
if (!v)
|
|
|
|
return REBASE_FALSE;
|
|
|
|
else if (v > 0)
|
|
|
|
return REBASE_TRUE;
|
|
|
|
else if (!strcmp(value, "preserve"))
|
|
|
|
return REBASE_PRESERVE;
|
2016-01-13 13:17:15 +01:00
|
|
|
else if (!strcmp(value, "interactive"))
|
|
|
|
return REBASE_INTERACTIVE;
|
pull: teach git pull about --rebase
Since cd67e4d (Teach 'git pull' about --rebase, 2007-11-28), if the
--rebase option is set, git-rebase is run instead of git-merge.
Re-implement this by introducing run_rebase(), which is called instead
of run_merge() if opt_rebase is a true value.
Since c85c792 (pull --rebase: be cleverer with rebased upstream
branches, 2008-01-26), git-pull handles the case where the upstream
branch was rebased since it was last fetched. The fork point (old remote
ref) of the branch from the upstream branch is calculated before fetch,
and then rebased from onto the new remote head (merge_head) after fetch.
Re-implement this by introducing get_merge_branch_2() and
get_merge_branch_1() to find the upstream branch for the
specified/current branch, and get_rebase_fork_point() which will find
the fork point between the upstream branch and current branch.
However, the above change created a problem where git-rebase cannot
detect commits that are already upstream, and thus may result in
unnecessary conflicts. cf65426 (pull --rebase: Avoid spurious conflicts
and reapplying unnecessary patches, 2010-08-12) fixes this by ignoring
the above old remote ref if it is contained within the merge base of the
merge head and the current branch.
This is re-implemented in run_rebase() where fork_point is not used if
it is the merge base returned by get_octopus_merge_base().
Helped-by: Stefan Beller <sbeller@google.com>
Helped-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Paul Tan <pyokagan@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2015-06-18 12:54:08 +02:00
|
|
|
|
|
|
|
if (fatal)
|
|
|
|
die(_("Invalid value for %s: %s"), key, value);
|
|
|
|
else
|
|
|
|
error(_("Invalid value for %s: %s"), key, value);
|
|
|
|
|
|
|
|
return REBASE_INVALID;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Callback for --rebase, which parses arg with parse_config_rebase().
|
|
|
|
*/
|
|
|
|
static int parse_opt_rebase(const struct option *opt, const char *arg, int unset)
|
|
|
|
{
|
|
|
|
enum rebase_type *value = opt->value;
|
|
|
|
|
|
|
|
if (arg)
|
|
|
|
*value = parse_config_rebase("--rebase", arg, 0);
|
|
|
|
else
|
|
|
|
*value = unset ? REBASE_FALSE : REBASE_TRUE;
|
|
|
|
return *value == REBASE_INVALID ? -1 : 0;
|
|
|
|
}
|
|
|
|
|
2015-06-14 10:41:51 +02:00
|
|
|
static const char * const pull_usage[] = {
|
2015-10-16 04:22:13 +02:00
|
|
|
N_("git pull [<options>] [<repository> [<refspec>...]]"),
|
2015-06-14 10:41:51 +02:00
|
|
|
NULL
|
|
|
|
};
|
|
|
|
|
2015-06-14 10:41:53 +02:00
|
|
|
/* Shared options */
|
|
|
|
static int opt_verbosity;
|
|
|
|
static char *opt_progress;
|
pull: optionally rebase submodules (remote submodule changes only)
Teach pull to optionally update submodules when '--recurse-submodules'
is provided. This will teach pull to run 'submodule update --rebase'
when the '--recurse-submodules' and '--rebase' flags are given under
specific circumstances.
On a rebase workflow:
=====================
1. Both sides change the submodule
------------------------------
Let's assume the following history in a submodule:
H---I---J---K---L local branch
\
M---N---O---P remote branch
and the following in the superproject (recorded submodule in parens):
A(H)---B(I)---F(K)---G(L) local branch
\
C(N)---D(N)---E(P) remote branch
In an ideal world this would rebase the submodule and rewrite
the submodule pointers that the superproject points at such that
the superproject looks like
A(H)---B(I) F(K')---G(L') rebased branch
\ /
C(N)---D(N)---E(P) remote branch
and the submodule as:
J---K---L (old dangeling tip)
/
H---I J'---K'---L' rebased branch
\ /
M---N---O---P remote branch
And if a conflict arises in the submodule the superproject rebase
would stop at that commit at which the submodule conflict occurs.
Currently a "pull --rebase" in the superproject produces
a merge conflict as the submodule pointer changes are
conflicting and cannot be resolved.
2. Local submodule changes only
-----------------------
Assuming histories as above, except that the remote branch
would not contain submodule changes, then a result as
A(H)---B(I) F(K)---G(L) rebased branch
\ /
C(I)---D(I)---E(I) remote branch
is desire-able. This is what currently happens in rebase.
If the recursive flag is given, the ideal git would
produce a superproject as:
A(H)---B(I) F(K')---G(L') rebased branch (incl. sub rebase!)
\ /
C(I)---D(I)---E(I) remote branch
and the submodule as:
J---K---L (old dangeling tip)
/
H---I J'---K'---L' locally rebased branch
\ /
M---N---O---P advanced branch
This patch doesn't address this issue, however
a test is added that this fails up front.
3. Remote submodule changes only
----------------------
Assuming histories as in (1) except that the local superproject branch
would not have touched the submodule the rebase already works out in the
superproject with no conflicts:
A(H)---B(I) F(P)---G(P) rebased branch (no sub changes)
\ /
C(N)---D(N)---E(P) remote branch
The recurse flag as presented in this patch would additionally
update the submodule as:
H---I J'---K'---L' rebased branch
\ /
M---N---O---P remote branch
As neither J, K, L nor J', K', L' are referred to from the superproject,
no rewriting of the superproject commits is required.
Conclusion for 'pull --rebase --recursive'
-----------------------------------------
If there are no local superproject changes it is sufficient to call
"submodule update --rebase" as this produces the desired results. In case
of conflicts, the behavior is the same as in 'submodule update --recursive'
which is assumed to be sane.
This patch implements (3) only.
On a merge workflow:
====================
We'll start off with the same underlying DAG as in (1) in the rebase
workflow. So in an ideal world a 'pull --merge --recursive' would
produce this:
H---I---J---K---L----X
\ /
M---N---O---P
with X as the new merge-commit in the submodule and the superproject
as:
A(H)---B(I)---F(K)---G(L)---Y(X)
\ /
C(N)---D(N)---E(P)
However modifying the submodules on the fly is not supported in git-merge
such that Y(X) is not easy to produce in a single patch. In fact git-merge
doesn't know about submodules at all.
However when at least one side does not contain commits touching the
submodule at all, then we do not need to perform the merge for the
submodule but a fast-forward can be done via checking out either L or P
in the submodule. This strategy is implemented in 68d03e4a6e (Implement
automatic fast-forward merge for submodules, 2010-07-07) already, so
to align with the rebase behavior we need to also update the worktree
of the submodule.
Signed-off-by: Brandon Williams <bmwill@google.com>
Signed-off-by: Stefan Beller <sbeller@google.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-06-23 21:13:02 +02:00
|
|
|
static int recurse_submodules = RECURSE_SUBMODULES_DEFAULT;
|
2015-06-14 10:41:53 +02:00
|
|
|
|
pull: teach git pull about --rebase
Since cd67e4d (Teach 'git pull' about --rebase, 2007-11-28), if the
--rebase option is set, git-rebase is run instead of git-merge.
Re-implement this by introducing run_rebase(), which is called instead
of run_merge() if opt_rebase is a true value.
Since c85c792 (pull --rebase: be cleverer with rebased upstream
branches, 2008-01-26), git-pull handles the case where the upstream
branch was rebased since it was last fetched. The fork point (old remote
ref) of the branch from the upstream branch is calculated before fetch,
and then rebased from onto the new remote head (merge_head) after fetch.
Re-implement this by introducing get_merge_branch_2() and
get_merge_branch_1() to find the upstream branch for the
specified/current branch, and get_rebase_fork_point() which will find
the fork point between the upstream branch and current branch.
However, the above change created a problem where git-rebase cannot
detect commits that are already upstream, and thus may result in
unnecessary conflicts. cf65426 (pull --rebase: Avoid spurious conflicts
and reapplying unnecessary patches, 2010-08-12) fixes this by ignoring
the above old remote ref if it is contained within the merge base of the
merge head and the current branch.
This is re-implemented in run_rebase() where fork_point is not used if
it is the merge base returned by get_octopus_merge_base().
Helped-by: Stefan Beller <sbeller@google.com>
Helped-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Paul Tan <pyokagan@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2015-06-18 12:54:08 +02:00
|
|
|
/* Options passed to git-merge or git-rebase */
|
2015-06-18 12:54:09 +02:00
|
|
|
static enum rebase_type opt_rebase = -1;
|
pull: pass git-merge's options to git-merge
Specify git-merge's options in the option list, and pass any specified
options to git-merge.
These options are:
* -n, --stat, --summary: since d8abe14 (merge, pull: introduce
'--(no-)stat' option, 2008-04-06)
* --log: since efb779f (merge, pull: add '--(no-)log' command line
option, 2008-04-06)
* --squash: since 7d0c688 (git-merge --squash, 2006-06-23)
* --commit: since 5072a32 (Teach git-pull about --[no-]ff, --no-squash
and --commit, 2007-10-29)
* --edit: since 8580830 ("git pull" doesn't know "--edit", 2012-02-11)
* --ff, --ff-only: since 5072a32 (Teach git-pull about --[no-]ff,
--no-squash and --commit, 2007-10-29)
* --verify-signatures: since efed002 (merge/pull: verify GPG signatures
of commits being merged, 2013-03-31)
* -s, --strategy: since 60fb5b2 (Use git-merge in git-pull (second
try)., 2005-09-25)
* -X, --strategy-option: since ee2c795 (Teach git-pull to pass
-X<option> to git-merge, 2009-11-25)
* -S, --gpg-sign: since ea230d8 (pull: add the --gpg-sign option.,
2014-02-10)
Signed-off-by: Paul Tan <pyokagan@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2015-06-14 10:41:54 +02:00
|
|
|
static char *opt_diffstat;
|
|
|
|
static char *opt_log;
|
|
|
|
static char *opt_squash;
|
|
|
|
static char *opt_commit;
|
|
|
|
static char *opt_edit;
|
|
|
|
static char *opt_ff;
|
|
|
|
static char *opt_verify_signatures;
|
2016-03-21 19:18:03 +01:00
|
|
|
static int opt_autostash = -1;
|
2016-03-21 19:18:02 +01:00
|
|
|
static int config_autostash;
|
pull: pass git-merge's options to git-merge
Specify git-merge's options in the option list, and pass any specified
options to git-merge.
These options are:
* -n, --stat, --summary: since d8abe14 (merge, pull: introduce
'--(no-)stat' option, 2008-04-06)
* --log: since efb779f (merge, pull: add '--(no-)log' command line
option, 2008-04-06)
* --squash: since 7d0c688 (git-merge --squash, 2006-06-23)
* --commit: since 5072a32 (Teach git-pull about --[no-]ff, --no-squash
and --commit, 2007-10-29)
* --edit: since 8580830 ("git pull" doesn't know "--edit", 2012-02-11)
* --ff, --ff-only: since 5072a32 (Teach git-pull about --[no-]ff,
--no-squash and --commit, 2007-10-29)
* --verify-signatures: since efed002 (merge/pull: verify GPG signatures
of commits being merged, 2013-03-31)
* -s, --strategy: since 60fb5b2 (Use git-merge in git-pull (second
try)., 2005-09-25)
* -X, --strategy-option: since ee2c795 (Teach git-pull to pass
-X<option> to git-merge, 2009-11-25)
* -S, --gpg-sign: since ea230d8 (pull: add the --gpg-sign option.,
2014-02-10)
Signed-off-by: Paul Tan <pyokagan@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2015-06-14 10:41:54 +02:00
|
|
|
static struct argv_array opt_strategies = ARGV_ARRAY_INIT;
|
|
|
|
static struct argv_array opt_strategy_opts = ARGV_ARRAY_INIT;
|
|
|
|
static char *opt_gpg_sign;
|
2016-03-18 21:21:09 +01:00
|
|
|
static int opt_allow_unrelated_histories;
|
pull: pass git-merge's options to git-merge
Specify git-merge's options in the option list, and pass any specified
options to git-merge.
These options are:
* -n, --stat, --summary: since d8abe14 (merge, pull: introduce
'--(no-)stat' option, 2008-04-06)
* --log: since efb779f (merge, pull: add '--(no-)log' command line
option, 2008-04-06)
* --squash: since 7d0c688 (git-merge --squash, 2006-06-23)
* --commit: since 5072a32 (Teach git-pull about --[no-]ff, --no-squash
and --commit, 2007-10-29)
* --edit: since 8580830 ("git pull" doesn't know "--edit", 2012-02-11)
* --ff, --ff-only: since 5072a32 (Teach git-pull about --[no-]ff,
--no-squash and --commit, 2007-10-29)
* --verify-signatures: since efed002 (merge/pull: verify GPG signatures
of commits being merged, 2013-03-31)
* -s, --strategy: since 60fb5b2 (Use git-merge in git-pull (second
try)., 2005-09-25)
* -X, --strategy-option: since ee2c795 (Teach git-pull to pass
-X<option> to git-merge, 2009-11-25)
* -S, --gpg-sign: since ea230d8 (pull: add the --gpg-sign option.,
2014-02-10)
Signed-off-by: Paul Tan <pyokagan@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2015-06-14 10:41:54 +02:00
|
|
|
|
2015-06-18 12:54:01 +02:00
|
|
|
/* Options passed to git-fetch */
|
|
|
|
static char *opt_all;
|
|
|
|
static char *opt_append;
|
|
|
|
static char *opt_upload_pack;
|
|
|
|
static int opt_force;
|
|
|
|
static char *opt_tags;
|
|
|
|
static char *opt_prune;
|
2015-12-16 01:04:12 +01:00
|
|
|
static char *max_children;
|
2015-06-18 12:54:01 +02:00
|
|
|
static int opt_dry_run;
|
|
|
|
static char *opt_keep;
|
|
|
|
static char *opt_depth;
|
|
|
|
static char *opt_unshallow;
|
|
|
|
static char *opt_update_shallow;
|
|
|
|
static char *opt_refmap;
|
|
|
|
|
2015-06-14 10:41:51 +02:00
|
|
|
static struct option pull_options[] = {
|
2015-06-14 10:41:53 +02:00
|
|
|
/* Shared options */
|
|
|
|
OPT__VERBOSITY(&opt_verbosity),
|
|
|
|
OPT_PASSTHRU(0, "progress", &opt_progress, NULL,
|
|
|
|
N_("force progress reporting"),
|
|
|
|
PARSE_OPT_NOARG),
|
pull: optionally rebase submodules (remote submodule changes only)
Teach pull to optionally update submodules when '--recurse-submodules'
is provided. This will teach pull to run 'submodule update --rebase'
when the '--recurse-submodules' and '--rebase' flags are given under
specific circumstances.
On a rebase workflow:
=====================
1. Both sides change the submodule
------------------------------
Let's assume the following history in a submodule:
H---I---J---K---L local branch
\
M---N---O---P remote branch
and the following in the superproject (recorded submodule in parens):
A(H)---B(I)---F(K)---G(L) local branch
\
C(N)---D(N)---E(P) remote branch
In an ideal world this would rebase the submodule and rewrite
the submodule pointers that the superproject points at such that
the superproject looks like
A(H)---B(I) F(K')---G(L') rebased branch
\ /
C(N)---D(N)---E(P) remote branch
and the submodule as:
J---K---L (old dangeling tip)
/
H---I J'---K'---L' rebased branch
\ /
M---N---O---P remote branch
And if a conflict arises in the submodule the superproject rebase
would stop at that commit at which the submodule conflict occurs.
Currently a "pull --rebase" in the superproject produces
a merge conflict as the submodule pointer changes are
conflicting and cannot be resolved.
2. Local submodule changes only
-----------------------
Assuming histories as above, except that the remote branch
would not contain submodule changes, then a result as
A(H)---B(I) F(K)---G(L) rebased branch
\ /
C(I)---D(I)---E(I) remote branch
is desire-able. This is what currently happens in rebase.
If the recursive flag is given, the ideal git would
produce a superproject as:
A(H)---B(I) F(K')---G(L') rebased branch (incl. sub rebase!)
\ /
C(I)---D(I)---E(I) remote branch
and the submodule as:
J---K---L (old dangeling tip)
/
H---I J'---K'---L' locally rebased branch
\ /
M---N---O---P advanced branch
This patch doesn't address this issue, however
a test is added that this fails up front.
3. Remote submodule changes only
----------------------
Assuming histories as in (1) except that the local superproject branch
would not have touched the submodule the rebase already works out in the
superproject with no conflicts:
A(H)---B(I) F(P)---G(P) rebased branch (no sub changes)
\ /
C(N)---D(N)---E(P) remote branch
The recurse flag as presented in this patch would additionally
update the submodule as:
H---I J'---K'---L' rebased branch
\ /
M---N---O---P remote branch
As neither J, K, L nor J', K', L' are referred to from the superproject,
no rewriting of the superproject commits is required.
Conclusion for 'pull --rebase --recursive'
-----------------------------------------
If there are no local superproject changes it is sufficient to call
"submodule update --rebase" as this produces the desired results. In case
of conflicts, the behavior is the same as in 'submodule update --recursive'
which is assumed to be sane.
This patch implements (3) only.
On a merge workflow:
====================
We'll start off with the same underlying DAG as in (1) in the rebase
workflow. So in an ideal world a 'pull --merge --recursive' would
produce this:
H---I---J---K---L----X
\ /
M---N---O---P
with X as the new merge-commit in the submodule and the superproject
as:
A(H)---B(I)---F(K)---G(L)---Y(X)
\ /
C(N)---D(N)---E(P)
However modifying the submodules on the fly is not supported in git-merge
such that Y(X) is not easy to produce in a single patch. In fact git-merge
doesn't know about submodules at all.
However when at least one side does not contain commits touching the
submodule at all, then we do not need to perform the merge for the
submodule but a fast-forward can be done via checking out either L or P
in the submodule. This strategy is implemented in 68d03e4a6e (Implement
automatic fast-forward merge for submodules, 2010-07-07) already, so
to align with the rebase behavior we need to also update the worktree
of the submodule.
Signed-off-by: Brandon Williams <bmwill@google.com>
Signed-off-by: Stefan Beller <sbeller@google.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-06-23 21:13:02 +02:00
|
|
|
{ OPTION_CALLBACK, 0, "recurse-submodules",
|
|
|
|
&recurse_submodules, N_("on-demand"),
|
|
|
|
N_("control for recursive fetching of submodules"),
|
|
|
|
PARSE_OPT_OPTARG, option_fetch_parse_recurse_submodules },
|
2015-06-14 10:41:53 +02:00
|
|
|
|
pull: teach git pull about --rebase
Since cd67e4d (Teach 'git pull' about --rebase, 2007-11-28), if the
--rebase option is set, git-rebase is run instead of git-merge.
Re-implement this by introducing run_rebase(), which is called instead
of run_merge() if opt_rebase is a true value.
Since c85c792 (pull --rebase: be cleverer with rebased upstream
branches, 2008-01-26), git-pull handles the case where the upstream
branch was rebased since it was last fetched. The fork point (old remote
ref) of the branch from the upstream branch is calculated before fetch,
and then rebased from onto the new remote head (merge_head) after fetch.
Re-implement this by introducing get_merge_branch_2() and
get_merge_branch_1() to find the upstream branch for the
specified/current branch, and get_rebase_fork_point() which will find
the fork point between the upstream branch and current branch.
However, the above change created a problem where git-rebase cannot
detect commits that are already upstream, and thus may result in
unnecessary conflicts. cf65426 (pull --rebase: Avoid spurious conflicts
and reapplying unnecessary patches, 2010-08-12) fixes this by ignoring
the above old remote ref if it is contained within the merge base of the
merge head and the current branch.
This is re-implemented in run_rebase() where fork_point is not used if
it is the merge base returned by get_octopus_merge_base().
Helped-by: Stefan Beller <sbeller@google.com>
Helped-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Paul Tan <pyokagan@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2015-06-18 12:54:08 +02:00
|
|
|
/* Options passed to git-merge or git-rebase */
|
pull: pass git-merge's options to git-merge
Specify git-merge's options in the option list, and pass any specified
options to git-merge.
These options are:
* -n, --stat, --summary: since d8abe14 (merge, pull: introduce
'--(no-)stat' option, 2008-04-06)
* --log: since efb779f (merge, pull: add '--(no-)log' command line
option, 2008-04-06)
* --squash: since 7d0c688 (git-merge --squash, 2006-06-23)
* --commit: since 5072a32 (Teach git-pull about --[no-]ff, --no-squash
and --commit, 2007-10-29)
* --edit: since 8580830 ("git pull" doesn't know "--edit", 2012-02-11)
* --ff, --ff-only: since 5072a32 (Teach git-pull about --[no-]ff,
--no-squash and --commit, 2007-10-29)
* --verify-signatures: since efed002 (merge/pull: verify GPG signatures
of commits being merged, 2013-03-31)
* -s, --strategy: since 60fb5b2 (Use git-merge in git-pull (second
try)., 2005-09-25)
* -X, --strategy-option: since ee2c795 (Teach git-pull to pass
-X<option> to git-merge, 2009-11-25)
* -S, --gpg-sign: since ea230d8 (pull: add the --gpg-sign option.,
2014-02-10)
Signed-off-by: Paul Tan <pyokagan@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2015-06-14 10:41:54 +02:00
|
|
|
OPT_GROUP(N_("Options related to merging")),
|
pull: teach git pull about --rebase
Since cd67e4d (Teach 'git pull' about --rebase, 2007-11-28), if the
--rebase option is set, git-rebase is run instead of git-merge.
Re-implement this by introducing run_rebase(), which is called instead
of run_merge() if opt_rebase is a true value.
Since c85c792 (pull --rebase: be cleverer with rebased upstream
branches, 2008-01-26), git-pull handles the case where the upstream
branch was rebased since it was last fetched. The fork point (old remote
ref) of the branch from the upstream branch is calculated before fetch,
and then rebased from onto the new remote head (merge_head) after fetch.
Re-implement this by introducing get_merge_branch_2() and
get_merge_branch_1() to find the upstream branch for the
specified/current branch, and get_rebase_fork_point() which will find
the fork point between the upstream branch and current branch.
However, the above change created a problem where git-rebase cannot
detect commits that are already upstream, and thus may result in
unnecessary conflicts. cf65426 (pull --rebase: Avoid spurious conflicts
and reapplying unnecessary patches, 2010-08-12) fixes this by ignoring
the above old remote ref if it is contained within the merge base of the
merge head and the current branch.
This is re-implemented in run_rebase() where fork_point is not used if
it is the merge base returned by get_octopus_merge_base().
Helped-by: Stefan Beller <sbeller@google.com>
Helped-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Paul Tan <pyokagan@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2015-06-18 12:54:08 +02:00
|
|
|
{ OPTION_CALLBACK, 'r', "rebase", &opt_rebase,
|
2016-01-13 13:17:15 +01:00
|
|
|
"false|true|preserve|interactive",
|
pull: teach git pull about --rebase
Since cd67e4d (Teach 'git pull' about --rebase, 2007-11-28), if the
--rebase option is set, git-rebase is run instead of git-merge.
Re-implement this by introducing run_rebase(), which is called instead
of run_merge() if opt_rebase is a true value.
Since c85c792 (pull --rebase: be cleverer with rebased upstream
branches, 2008-01-26), git-pull handles the case where the upstream
branch was rebased since it was last fetched. The fork point (old remote
ref) of the branch from the upstream branch is calculated before fetch,
and then rebased from onto the new remote head (merge_head) after fetch.
Re-implement this by introducing get_merge_branch_2() and
get_merge_branch_1() to find the upstream branch for the
specified/current branch, and get_rebase_fork_point() which will find
the fork point between the upstream branch and current branch.
However, the above change created a problem where git-rebase cannot
detect commits that are already upstream, and thus may result in
unnecessary conflicts. cf65426 (pull --rebase: Avoid spurious conflicts
and reapplying unnecessary patches, 2010-08-12) fixes this by ignoring
the above old remote ref if it is contained within the merge base of the
merge head and the current branch.
This is re-implemented in run_rebase() where fork_point is not used if
it is the merge base returned by get_octopus_merge_base().
Helped-by: Stefan Beller <sbeller@google.com>
Helped-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Paul Tan <pyokagan@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2015-06-18 12:54:08 +02:00
|
|
|
N_("incorporate changes by rebasing rather than merging"),
|
|
|
|
PARSE_OPT_OPTARG, parse_opt_rebase },
|
pull: pass git-merge's options to git-merge
Specify git-merge's options in the option list, and pass any specified
options to git-merge.
These options are:
* -n, --stat, --summary: since d8abe14 (merge, pull: introduce
'--(no-)stat' option, 2008-04-06)
* --log: since efb779f (merge, pull: add '--(no-)log' command line
option, 2008-04-06)
* --squash: since 7d0c688 (git-merge --squash, 2006-06-23)
* --commit: since 5072a32 (Teach git-pull about --[no-]ff, --no-squash
and --commit, 2007-10-29)
* --edit: since 8580830 ("git pull" doesn't know "--edit", 2012-02-11)
* --ff, --ff-only: since 5072a32 (Teach git-pull about --[no-]ff,
--no-squash and --commit, 2007-10-29)
* --verify-signatures: since efed002 (merge/pull: verify GPG signatures
of commits being merged, 2013-03-31)
* -s, --strategy: since 60fb5b2 (Use git-merge in git-pull (second
try)., 2005-09-25)
* -X, --strategy-option: since ee2c795 (Teach git-pull to pass
-X<option> to git-merge, 2009-11-25)
* -S, --gpg-sign: since ea230d8 (pull: add the --gpg-sign option.,
2014-02-10)
Signed-off-by: Paul Tan <pyokagan@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2015-06-14 10:41:54 +02:00
|
|
|
OPT_PASSTHRU('n', NULL, &opt_diffstat, NULL,
|
|
|
|
N_("do not show a diffstat at the end of the merge"),
|
|
|
|
PARSE_OPT_NOARG | PARSE_OPT_NONEG),
|
|
|
|
OPT_PASSTHRU(0, "stat", &opt_diffstat, NULL,
|
|
|
|
N_("show a diffstat at the end of the merge"),
|
|
|
|
PARSE_OPT_NOARG),
|
|
|
|
OPT_PASSTHRU(0, "summary", &opt_diffstat, NULL,
|
|
|
|
N_("(synonym to --stat)"),
|
|
|
|
PARSE_OPT_NOARG | PARSE_OPT_HIDDEN),
|
|
|
|
OPT_PASSTHRU(0, "log", &opt_log, N_("n"),
|
|
|
|
N_("add (at most <n>) entries from shortlog to merge commit message"),
|
|
|
|
PARSE_OPT_OPTARG),
|
|
|
|
OPT_PASSTHRU(0, "squash", &opt_squash, NULL,
|
|
|
|
N_("create a single commit instead of doing a merge"),
|
|
|
|
PARSE_OPT_NOARG),
|
|
|
|
OPT_PASSTHRU(0, "commit", &opt_commit, NULL,
|
|
|
|
N_("perform a commit if the merge succeeds (default)"),
|
|
|
|
PARSE_OPT_NOARG),
|
|
|
|
OPT_PASSTHRU(0, "edit", &opt_edit, NULL,
|
|
|
|
N_("edit message before committing"),
|
|
|
|
PARSE_OPT_NOARG),
|
|
|
|
OPT_PASSTHRU(0, "ff", &opt_ff, NULL,
|
|
|
|
N_("allow fast-forward"),
|
|
|
|
PARSE_OPT_NOARG),
|
|
|
|
OPT_PASSTHRU(0, "ff-only", &opt_ff, NULL,
|
|
|
|
N_("abort if fast-forward is not possible"),
|
|
|
|
PARSE_OPT_NOARG | PARSE_OPT_NONEG),
|
|
|
|
OPT_PASSTHRU(0, "verify-signatures", &opt_verify_signatures, NULL,
|
|
|
|
N_("verify that the named commit has a valid GPG signature"),
|
|
|
|
PARSE_OPT_NOARG),
|
2016-03-21 19:18:03 +01:00
|
|
|
OPT_BOOL(0, "autostash", &opt_autostash,
|
|
|
|
N_("automatically stash/stash pop before and after rebase")),
|
pull: pass git-merge's options to git-merge
Specify git-merge's options in the option list, and pass any specified
options to git-merge.
These options are:
* -n, --stat, --summary: since d8abe14 (merge, pull: introduce
'--(no-)stat' option, 2008-04-06)
* --log: since efb779f (merge, pull: add '--(no-)log' command line
option, 2008-04-06)
* --squash: since 7d0c688 (git-merge --squash, 2006-06-23)
* --commit: since 5072a32 (Teach git-pull about --[no-]ff, --no-squash
and --commit, 2007-10-29)
* --edit: since 8580830 ("git pull" doesn't know "--edit", 2012-02-11)
* --ff, --ff-only: since 5072a32 (Teach git-pull about --[no-]ff,
--no-squash and --commit, 2007-10-29)
* --verify-signatures: since efed002 (merge/pull: verify GPG signatures
of commits being merged, 2013-03-31)
* -s, --strategy: since 60fb5b2 (Use git-merge in git-pull (second
try)., 2005-09-25)
* -X, --strategy-option: since ee2c795 (Teach git-pull to pass
-X<option> to git-merge, 2009-11-25)
* -S, --gpg-sign: since ea230d8 (pull: add the --gpg-sign option.,
2014-02-10)
Signed-off-by: Paul Tan <pyokagan@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2015-06-14 10:41:54 +02:00
|
|
|
OPT_PASSTHRU_ARGV('s', "strategy", &opt_strategies, N_("strategy"),
|
|
|
|
N_("merge strategy to use"),
|
|
|
|
0),
|
|
|
|
OPT_PASSTHRU_ARGV('X', "strategy-option", &opt_strategy_opts,
|
|
|
|
N_("option=value"),
|
|
|
|
N_("option for selected merge strategy"),
|
|
|
|
0),
|
|
|
|
OPT_PASSTHRU('S', "gpg-sign", &opt_gpg_sign, N_("key-id"),
|
|
|
|
N_("GPG sign commit"),
|
|
|
|
PARSE_OPT_OPTARG),
|
2016-03-18 21:21:09 +01:00
|
|
|
OPT_SET_INT(0, "allow-unrelated-histories",
|
|
|
|
&opt_allow_unrelated_histories,
|
|
|
|
N_("allow merging unrelated histories"), 1),
|
pull: pass git-merge's options to git-merge
Specify git-merge's options in the option list, and pass any specified
options to git-merge.
These options are:
* -n, --stat, --summary: since d8abe14 (merge, pull: introduce
'--(no-)stat' option, 2008-04-06)
* --log: since efb779f (merge, pull: add '--(no-)log' command line
option, 2008-04-06)
* --squash: since 7d0c688 (git-merge --squash, 2006-06-23)
* --commit: since 5072a32 (Teach git-pull about --[no-]ff, --no-squash
and --commit, 2007-10-29)
* --edit: since 8580830 ("git pull" doesn't know "--edit", 2012-02-11)
* --ff, --ff-only: since 5072a32 (Teach git-pull about --[no-]ff,
--no-squash and --commit, 2007-10-29)
* --verify-signatures: since efed002 (merge/pull: verify GPG signatures
of commits being merged, 2013-03-31)
* -s, --strategy: since 60fb5b2 (Use git-merge in git-pull (second
try)., 2005-09-25)
* -X, --strategy-option: since ee2c795 (Teach git-pull to pass
-X<option> to git-merge, 2009-11-25)
* -S, --gpg-sign: since ea230d8 (pull: add the --gpg-sign option.,
2014-02-10)
Signed-off-by: Paul Tan <pyokagan@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2015-06-14 10:41:54 +02:00
|
|
|
|
2015-06-18 12:54:01 +02:00
|
|
|
/* Options passed to git-fetch */
|
|
|
|
OPT_GROUP(N_("Options related to fetching")),
|
|
|
|
OPT_PASSTHRU(0, "all", &opt_all, NULL,
|
|
|
|
N_("fetch from all remotes"),
|
|
|
|
PARSE_OPT_NOARG),
|
|
|
|
OPT_PASSTHRU('a', "append", &opt_append, NULL,
|
|
|
|
N_("append to .git/FETCH_HEAD instead of overwriting"),
|
|
|
|
PARSE_OPT_NOARG),
|
|
|
|
OPT_PASSTHRU(0, "upload-pack", &opt_upload_pack, N_("path"),
|
|
|
|
N_("path to upload pack on remote end"),
|
|
|
|
0),
|
|
|
|
OPT__FORCE(&opt_force, N_("force overwrite of local branch")),
|
|
|
|
OPT_PASSTHRU('t', "tags", &opt_tags, NULL,
|
|
|
|
N_("fetch all tags and associated objects"),
|
|
|
|
PARSE_OPT_NOARG),
|
|
|
|
OPT_PASSTHRU('p', "prune", &opt_prune, NULL,
|
|
|
|
N_("prune remote-tracking branches no longer on remote"),
|
|
|
|
PARSE_OPT_NOARG),
|
2015-12-16 01:04:12 +01:00
|
|
|
OPT_PASSTHRU('j', "jobs", &max_children, N_("n"),
|
|
|
|
N_("number of submodules pulled in parallel"),
|
|
|
|
PARSE_OPT_OPTARG),
|
2015-06-18 12:54:01 +02:00
|
|
|
OPT_BOOL(0, "dry-run", &opt_dry_run,
|
|
|
|
N_("dry run")),
|
|
|
|
OPT_PASSTHRU('k', "keep", &opt_keep, NULL,
|
|
|
|
N_("keep downloaded pack"),
|
|
|
|
PARSE_OPT_NOARG),
|
|
|
|
OPT_PASSTHRU(0, "depth", &opt_depth, N_("depth"),
|
|
|
|
N_("deepen history of shallow clone"),
|
|
|
|
0),
|
|
|
|
OPT_PASSTHRU(0, "unshallow", &opt_unshallow, NULL,
|
|
|
|
N_("convert to a complete repository"),
|
|
|
|
PARSE_OPT_NONEG | PARSE_OPT_NOARG),
|
|
|
|
OPT_PASSTHRU(0, "update-shallow", &opt_update_shallow, NULL,
|
|
|
|
N_("accept refs that update .git/shallow"),
|
|
|
|
PARSE_OPT_NOARG),
|
|
|
|
OPT_PASSTHRU(0, "refmap", &opt_refmap, N_("refmap"),
|
|
|
|
N_("specify fetch refmap"),
|
|
|
|
PARSE_OPT_NONEG),
|
|
|
|
|
2015-06-14 10:41:51 +02:00
|
|
|
OPT_END()
|
|
|
|
};
|
|
|
|
|
2015-06-14 10:41:53 +02:00
|
|
|
/**
|
|
|
|
* Pushes "-q" or "-v" switches into arr to match the opt_verbosity level.
|
|
|
|
*/
|
|
|
|
static void argv_push_verbosity(struct argv_array *arr)
|
|
|
|
{
|
|
|
|
int verbosity;
|
|
|
|
|
|
|
|
for (verbosity = opt_verbosity; verbosity > 0; verbosity--)
|
|
|
|
argv_array_push(arr, "-v");
|
|
|
|
|
|
|
|
for (verbosity = opt_verbosity; verbosity < 0; verbosity++)
|
|
|
|
argv_array_push(arr, "-q");
|
|
|
|
}
|
|
|
|
|
2015-06-18 12:54:01 +02:00
|
|
|
/**
|
|
|
|
* Pushes "-f" switches into arr to match the opt_force level.
|
|
|
|
*/
|
|
|
|
static void argv_push_force(struct argv_array *arr)
|
|
|
|
{
|
|
|
|
int force = opt_force;
|
|
|
|
while (force-- > 0)
|
|
|
|
argv_array_push(arr, "-f");
|
|
|
|
}
|
|
|
|
|
2015-06-18 12:54:07 +02:00
|
|
|
/**
|
|
|
|
* Sets the GIT_REFLOG_ACTION environment variable to the concatenation of argv
|
|
|
|
*/
|
|
|
|
static void set_reflog_message(int argc, const char **argv)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
struct strbuf msg = STRBUF_INIT;
|
|
|
|
|
|
|
|
for (i = 0; i < argc; i++) {
|
|
|
|
if (i)
|
|
|
|
strbuf_addch(&msg, ' ');
|
|
|
|
strbuf_addstr(&msg, argv[i]);
|
|
|
|
}
|
|
|
|
|
|
|
|
setenv("GIT_REFLOG_ACTION", msg.buf, 0);
|
|
|
|
|
|
|
|
strbuf_release(&msg);
|
|
|
|
}
|
|
|
|
|
2015-06-18 12:54:03 +02:00
|
|
|
/**
|
|
|
|
* If pull.ff is unset, returns NULL. If pull.ff is "true", returns "--ff". If
|
|
|
|
* pull.ff is "false", returns "--no-ff". If pull.ff is "only", returns
|
|
|
|
* "--ff-only". Otherwise, if pull.ff is set to an invalid value, die with an
|
|
|
|
* error.
|
|
|
|
*/
|
|
|
|
static const char *config_get_ff(void)
|
|
|
|
{
|
|
|
|
const char *value;
|
|
|
|
|
|
|
|
if (git_config_get_value("pull.ff", &value))
|
|
|
|
return NULL;
|
|
|
|
|
2017-08-07 20:20:49 +02:00
|
|
|
switch (git_parse_maybe_bool(value)) {
|
2015-06-18 12:54:03 +02:00
|
|
|
case 0:
|
|
|
|
return "--no-ff";
|
|
|
|
case 1:
|
|
|
|
return "--ff";
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!strcmp(value, "only"))
|
|
|
|
return "--ff-only";
|
|
|
|
|
|
|
|
die(_("Invalid value for pull.ff: %s"), value);
|
|
|
|
}
|
|
|
|
|
2015-06-18 12:54:09 +02:00
|
|
|
/**
|
|
|
|
* Returns the default configured value for --rebase. It first looks for the
|
|
|
|
* value of "branch.$curr_branch.rebase", where $curr_branch is the current
|
|
|
|
* branch, and if HEAD is detached or the configuration key does not exist,
|
|
|
|
* looks for the value of "pull.rebase". If both configuration keys do not
|
|
|
|
* exist, returns REBASE_FALSE.
|
|
|
|
*/
|
|
|
|
static enum rebase_type config_get_rebase(void)
|
|
|
|
{
|
|
|
|
struct branch *curr_branch = branch_get("HEAD");
|
|
|
|
const char *value;
|
|
|
|
|
|
|
|
if (curr_branch) {
|
|
|
|
char *key = xstrfmt("branch.%s.rebase", curr_branch->name);
|
|
|
|
|
|
|
|
if (!git_config_get_value(key, &value)) {
|
|
|
|
enum rebase_type ret = parse_config_rebase(key, value, 1);
|
|
|
|
free(key);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
free(key);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!git_config_get_value("pull.rebase", &value))
|
|
|
|
return parse_config_rebase("pull.rebase", value, 1);
|
|
|
|
|
|
|
|
return REBASE_FALSE;
|
|
|
|
}
|
|
|
|
|
2016-03-21 19:18:02 +01:00
|
|
|
/**
|
|
|
|
* Read config variables.
|
|
|
|
*/
|
|
|
|
static int git_pull_config(const char *var, const char *value, void *cb)
|
|
|
|
{
|
|
|
|
if (!strcmp(var, "rebase.autostash")) {
|
|
|
|
config_autostash = git_config_bool(var, value);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
return git_default_config(var, value, cb);
|
|
|
|
}
|
|
|
|
|
pull: error on no merge candidates
Commit a8c9bef (pull: improve advice for unconfigured error case,
2009-10-05) fully established the current advices given by git-pull for
the different cases where git-fetch will not have anything marked for
merge:
1. We fetched from a specific remote, and a refspec was given, but it
ended up not fetching anything. This is usually because the user
provided a wildcard refspec which had no matches on the remote end.
2. We fetched from a non-default remote, but didn't specify a branch to
merge. We can't use the configured one because it applies to the
default remote, and thus the user must specify the branches to merge.
3. We fetched from the branch's or repo's default remote, but:
a. We are not on a branch, so there will never be a configured branch
to merge with.
b. We are on a branch, but there is no configured branch to merge
with.
4. We fetched from the branch's or repo's default remote, but the
configured branch to merge didn't get fetched (either it doesn't
exist, or wasn't part of the configured fetch refspec)
Re-implement the above behavior by implementing get_merge_heads() to
parse the heads in FETCH_HEAD for merging, and implementing
die_no_merge_candidates(), which will be called when FETCH_HEAD has no
heads for merging.
Helped-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Helped-by: Junio C Hamano <gitster@pobox.com>
Signed-off-by: Paul Tan <pyokagan@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2015-06-18 12:54:02 +02:00
|
|
|
/**
|
|
|
|
* Appends merge candidates from FETCH_HEAD that are not marked not-for-merge
|
|
|
|
* into merge_heads.
|
|
|
|
*/
|
2017-03-31 03:40:00 +02:00
|
|
|
static void get_merge_heads(struct oid_array *merge_heads)
|
pull: error on no merge candidates
Commit a8c9bef (pull: improve advice for unconfigured error case,
2009-10-05) fully established the current advices given by git-pull for
the different cases where git-fetch will not have anything marked for
merge:
1. We fetched from a specific remote, and a refspec was given, but it
ended up not fetching anything. This is usually because the user
provided a wildcard refspec which had no matches on the remote end.
2. We fetched from a non-default remote, but didn't specify a branch to
merge. We can't use the configured one because it applies to the
default remote, and thus the user must specify the branches to merge.
3. We fetched from the branch's or repo's default remote, but:
a. We are not on a branch, so there will never be a configured branch
to merge with.
b. We are on a branch, but there is no configured branch to merge
with.
4. We fetched from the branch's or repo's default remote, but the
configured branch to merge didn't get fetched (either it doesn't
exist, or wasn't part of the configured fetch refspec)
Re-implement the above behavior by implementing get_merge_heads() to
parse the heads in FETCH_HEAD for merging, and implementing
die_no_merge_candidates(), which will be called when FETCH_HEAD has no
heads for merging.
Helped-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Helped-by: Junio C Hamano <gitster@pobox.com>
Signed-off-by: Paul Tan <pyokagan@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2015-06-18 12:54:02 +02:00
|
|
|
{
|
2017-04-20 23:08:54 +02:00
|
|
|
const char *filename = git_path_fetch_head();
|
pull: error on no merge candidates
Commit a8c9bef (pull: improve advice for unconfigured error case,
2009-10-05) fully established the current advices given by git-pull for
the different cases where git-fetch will not have anything marked for
merge:
1. We fetched from a specific remote, and a refspec was given, but it
ended up not fetching anything. This is usually because the user
provided a wildcard refspec which had no matches on the remote end.
2. We fetched from a non-default remote, but didn't specify a branch to
merge. We can't use the configured one because it applies to the
default remote, and thus the user must specify the branches to merge.
3. We fetched from the branch's or repo's default remote, but:
a. We are not on a branch, so there will never be a configured branch
to merge with.
b. We are on a branch, but there is no configured branch to merge
with.
4. We fetched from the branch's or repo's default remote, but the
configured branch to merge didn't get fetched (either it doesn't
exist, or wasn't part of the configured fetch refspec)
Re-implement the above behavior by implementing get_merge_heads() to
parse the heads in FETCH_HEAD for merging, and implementing
die_no_merge_candidates(), which will be called when FETCH_HEAD has no
heads for merging.
Helped-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Helped-by: Junio C Hamano <gitster@pobox.com>
Signed-off-by: Paul Tan <pyokagan@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2015-06-18 12:54:02 +02:00
|
|
|
FILE *fp;
|
|
|
|
struct strbuf sb = STRBUF_INIT;
|
2017-03-26 18:01:27 +02:00
|
|
|
struct object_id oid;
|
pull: error on no merge candidates
Commit a8c9bef (pull: improve advice for unconfigured error case,
2009-10-05) fully established the current advices given by git-pull for
the different cases where git-fetch will not have anything marked for
merge:
1. We fetched from a specific remote, and a refspec was given, but it
ended up not fetching anything. This is usually because the user
provided a wildcard refspec which had no matches on the remote end.
2. We fetched from a non-default remote, but didn't specify a branch to
merge. We can't use the configured one because it applies to the
default remote, and thus the user must specify the branches to merge.
3. We fetched from the branch's or repo's default remote, but:
a. We are not on a branch, so there will never be a configured branch
to merge with.
b. We are on a branch, but there is no configured branch to merge
with.
4. We fetched from the branch's or repo's default remote, but the
configured branch to merge didn't get fetched (either it doesn't
exist, or wasn't part of the configured fetch refspec)
Re-implement the above behavior by implementing get_merge_heads() to
parse the heads in FETCH_HEAD for merging, and implementing
die_no_merge_candidates(), which will be called when FETCH_HEAD has no
heads for merging.
Helped-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Helped-by: Junio C Hamano <gitster@pobox.com>
Signed-off-by: Paul Tan <pyokagan@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2015-06-18 12:54:02 +02:00
|
|
|
|
2017-05-03 12:16:46 +02:00
|
|
|
fp = xfopen(filename, "r");
|
2016-01-14 00:31:17 +01:00
|
|
|
while (strbuf_getline_lf(&sb, fp) != EOF) {
|
2017-03-26 18:01:27 +02:00
|
|
|
if (get_oid_hex(sb.buf, &oid))
|
pull: error on no merge candidates
Commit a8c9bef (pull: improve advice for unconfigured error case,
2009-10-05) fully established the current advices given by git-pull for
the different cases where git-fetch will not have anything marked for
merge:
1. We fetched from a specific remote, and a refspec was given, but it
ended up not fetching anything. This is usually because the user
provided a wildcard refspec which had no matches on the remote end.
2. We fetched from a non-default remote, but didn't specify a branch to
merge. We can't use the configured one because it applies to the
default remote, and thus the user must specify the branches to merge.
3. We fetched from the branch's or repo's default remote, but:
a. We are not on a branch, so there will never be a configured branch
to merge with.
b. We are on a branch, but there is no configured branch to merge
with.
4. We fetched from the branch's or repo's default remote, but the
configured branch to merge didn't get fetched (either it doesn't
exist, or wasn't part of the configured fetch refspec)
Re-implement the above behavior by implementing get_merge_heads() to
parse the heads in FETCH_HEAD for merging, and implementing
die_no_merge_candidates(), which will be called when FETCH_HEAD has no
heads for merging.
Helped-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Helped-by: Junio C Hamano <gitster@pobox.com>
Signed-off-by: Paul Tan <pyokagan@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2015-06-18 12:54:02 +02:00
|
|
|
continue; /* invalid line: does not start with SHA1 */
|
|
|
|
if (starts_with(sb.buf + GIT_SHA1_HEXSZ, "\tnot-for-merge\t"))
|
|
|
|
continue; /* ref is not-for-merge */
|
2017-03-31 03:40:00 +02:00
|
|
|
oid_array_append(merge_heads, &oid);
|
pull: error on no merge candidates
Commit a8c9bef (pull: improve advice for unconfigured error case,
2009-10-05) fully established the current advices given by git-pull for
the different cases where git-fetch will not have anything marked for
merge:
1. We fetched from a specific remote, and a refspec was given, but it
ended up not fetching anything. This is usually because the user
provided a wildcard refspec which had no matches on the remote end.
2. We fetched from a non-default remote, but didn't specify a branch to
merge. We can't use the configured one because it applies to the
default remote, and thus the user must specify the branches to merge.
3. We fetched from the branch's or repo's default remote, but:
a. We are not on a branch, so there will never be a configured branch
to merge with.
b. We are on a branch, but there is no configured branch to merge
with.
4. We fetched from the branch's or repo's default remote, but the
configured branch to merge didn't get fetched (either it doesn't
exist, or wasn't part of the configured fetch refspec)
Re-implement the above behavior by implementing get_merge_heads() to
parse the heads in FETCH_HEAD for merging, and implementing
die_no_merge_candidates(), which will be called when FETCH_HEAD has no
heads for merging.
Helped-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Helped-by: Junio C Hamano <gitster@pobox.com>
Signed-off-by: Paul Tan <pyokagan@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2015-06-18 12:54:02 +02:00
|
|
|
}
|
|
|
|
fclose(fp);
|
|
|
|
strbuf_release(&sb);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Used by die_no_merge_candidates() as a for_each_remote() callback to
|
|
|
|
* retrieve the name of the remote if the repository only has one remote.
|
|
|
|
*/
|
|
|
|
static int get_only_remote(struct remote *remote, void *cb_data)
|
|
|
|
{
|
|
|
|
const char **remote_name = cb_data;
|
|
|
|
|
|
|
|
if (*remote_name)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
*remote_name = remote->name;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Dies with the appropriate reason for why there are no merge candidates:
|
|
|
|
*
|
|
|
|
* 1. We fetched from a specific remote, and a refspec was given, but it ended
|
|
|
|
* up not fetching anything. This is usually because the user provided a
|
|
|
|
* wildcard refspec which had no matches on the remote end.
|
|
|
|
*
|
|
|
|
* 2. We fetched from a non-default remote, but didn't specify a branch to
|
|
|
|
* merge. We can't use the configured one because it applies to the default
|
|
|
|
* remote, thus the user must specify the branches to merge.
|
|
|
|
*
|
|
|
|
* 3. We fetched from the branch's or repo's default remote, but:
|
|
|
|
*
|
|
|
|
* a. We are not on a branch, so there will never be a configured branch to
|
|
|
|
* merge with.
|
|
|
|
*
|
|
|
|
* b. We are on a branch, but there is no configured branch to merge with.
|
|
|
|
*
|
|
|
|
* 4. We fetched from the branch's or repo's default remote, but the configured
|
|
|
|
* branch to merge didn't get fetched. (Either it doesn't exist, or wasn't
|
|
|
|
* part of the configured fetch refspec.)
|
|
|
|
*/
|
|
|
|
static void NORETURN die_no_merge_candidates(const char *repo, const char **refspecs)
|
|
|
|
{
|
|
|
|
struct branch *curr_branch = branch_get("HEAD");
|
|
|
|
const char *remote = curr_branch ? curr_branch->remote_name : NULL;
|
|
|
|
|
|
|
|
if (*refspecs) {
|
2015-06-18 12:54:11 +02:00
|
|
|
if (opt_rebase)
|
|
|
|
fprintf_ln(stderr, _("There is no candidate for rebasing against among the refs that you just fetched."));
|
|
|
|
else
|
|
|
|
fprintf_ln(stderr, _("There are no candidates for merging among the refs that you just fetched."));
|
pull: error on no merge candidates
Commit a8c9bef (pull: improve advice for unconfigured error case,
2009-10-05) fully established the current advices given by git-pull for
the different cases where git-fetch will not have anything marked for
merge:
1. We fetched from a specific remote, and a refspec was given, but it
ended up not fetching anything. This is usually because the user
provided a wildcard refspec which had no matches on the remote end.
2. We fetched from a non-default remote, but didn't specify a branch to
merge. We can't use the configured one because it applies to the
default remote, and thus the user must specify the branches to merge.
3. We fetched from the branch's or repo's default remote, but:
a. We are not on a branch, so there will never be a configured branch
to merge with.
b. We are on a branch, but there is no configured branch to merge
with.
4. We fetched from the branch's or repo's default remote, but the
configured branch to merge didn't get fetched (either it doesn't
exist, or wasn't part of the configured fetch refspec)
Re-implement the above behavior by implementing get_merge_heads() to
parse the heads in FETCH_HEAD for merging, and implementing
die_no_merge_candidates(), which will be called when FETCH_HEAD has no
heads for merging.
Helped-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Helped-by: Junio C Hamano <gitster@pobox.com>
Signed-off-by: Paul Tan <pyokagan@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2015-06-18 12:54:02 +02:00
|
|
|
fprintf_ln(stderr, _("Generally this means that you provided a wildcard refspec which had no\n"
|
|
|
|
"matches on the remote end."));
|
|
|
|
} else if (repo && curr_branch && (!remote || strcmp(repo, remote))) {
|
|
|
|
fprintf_ln(stderr, _("You asked to pull from the remote '%s', but did not specify\n"
|
|
|
|
"a branch. Because this is not the default configured remote\n"
|
|
|
|
"for your current branch, you must specify a branch on the command line."),
|
|
|
|
repo);
|
|
|
|
} else if (!curr_branch) {
|
|
|
|
fprintf_ln(stderr, _("You are not currently on a branch."));
|
2015-06-18 12:54:11 +02:00
|
|
|
if (opt_rebase)
|
|
|
|
fprintf_ln(stderr, _("Please specify which branch you want to rebase against."));
|
|
|
|
else
|
|
|
|
fprintf_ln(stderr, _("Please specify which branch you want to merge with."));
|
pull: error on no merge candidates
Commit a8c9bef (pull: improve advice for unconfigured error case,
2009-10-05) fully established the current advices given by git-pull for
the different cases where git-fetch will not have anything marked for
merge:
1. We fetched from a specific remote, and a refspec was given, but it
ended up not fetching anything. This is usually because the user
provided a wildcard refspec which had no matches on the remote end.
2. We fetched from a non-default remote, but didn't specify a branch to
merge. We can't use the configured one because it applies to the
default remote, and thus the user must specify the branches to merge.
3. We fetched from the branch's or repo's default remote, but:
a. We are not on a branch, so there will never be a configured branch
to merge with.
b. We are on a branch, but there is no configured branch to merge
with.
4. We fetched from the branch's or repo's default remote, but the
configured branch to merge didn't get fetched (either it doesn't
exist, or wasn't part of the configured fetch refspec)
Re-implement the above behavior by implementing get_merge_heads() to
parse the heads in FETCH_HEAD for merging, and implementing
die_no_merge_candidates(), which will be called when FETCH_HEAD has no
heads for merging.
Helped-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Helped-by: Junio C Hamano <gitster@pobox.com>
Signed-off-by: Paul Tan <pyokagan@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2015-06-18 12:54:02 +02:00
|
|
|
fprintf_ln(stderr, _("See git-pull(1) for details."));
|
|
|
|
fprintf(stderr, "\n");
|
2016-04-19 15:19:21 +02:00
|
|
|
fprintf_ln(stderr, " git pull %s %s", _("<remote>"), _("<branch>"));
|
pull: error on no merge candidates
Commit a8c9bef (pull: improve advice for unconfigured error case,
2009-10-05) fully established the current advices given by git-pull for
the different cases where git-fetch will not have anything marked for
merge:
1. We fetched from a specific remote, and a refspec was given, but it
ended up not fetching anything. This is usually because the user
provided a wildcard refspec which had no matches on the remote end.
2. We fetched from a non-default remote, but didn't specify a branch to
merge. We can't use the configured one because it applies to the
default remote, and thus the user must specify the branches to merge.
3. We fetched from the branch's or repo's default remote, but:
a. We are not on a branch, so there will never be a configured branch
to merge with.
b. We are on a branch, but there is no configured branch to merge
with.
4. We fetched from the branch's or repo's default remote, but the
configured branch to merge didn't get fetched (either it doesn't
exist, or wasn't part of the configured fetch refspec)
Re-implement the above behavior by implementing get_merge_heads() to
parse the heads in FETCH_HEAD for merging, and implementing
die_no_merge_candidates(), which will be called when FETCH_HEAD has no
heads for merging.
Helped-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Helped-by: Junio C Hamano <gitster@pobox.com>
Signed-off-by: Paul Tan <pyokagan@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2015-06-18 12:54:02 +02:00
|
|
|
fprintf(stderr, "\n");
|
|
|
|
} else if (!curr_branch->merge_nr) {
|
|
|
|
const char *remote_name = NULL;
|
|
|
|
|
|
|
|
if (for_each_remote(get_only_remote, &remote_name) || !remote_name)
|
2016-04-19 15:19:21 +02:00
|
|
|
remote_name = _("<remote>");
|
pull: error on no merge candidates
Commit a8c9bef (pull: improve advice for unconfigured error case,
2009-10-05) fully established the current advices given by git-pull for
the different cases where git-fetch will not have anything marked for
merge:
1. We fetched from a specific remote, and a refspec was given, but it
ended up not fetching anything. This is usually because the user
provided a wildcard refspec which had no matches on the remote end.
2. We fetched from a non-default remote, but didn't specify a branch to
merge. We can't use the configured one because it applies to the
default remote, and thus the user must specify the branches to merge.
3. We fetched from the branch's or repo's default remote, but:
a. We are not on a branch, so there will never be a configured branch
to merge with.
b. We are on a branch, but there is no configured branch to merge
with.
4. We fetched from the branch's or repo's default remote, but the
configured branch to merge didn't get fetched (either it doesn't
exist, or wasn't part of the configured fetch refspec)
Re-implement the above behavior by implementing get_merge_heads() to
parse the heads in FETCH_HEAD for merging, and implementing
die_no_merge_candidates(), which will be called when FETCH_HEAD has no
heads for merging.
Helped-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Helped-by: Junio C Hamano <gitster@pobox.com>
Signed-off-by: Paul Tan <pyokagan@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2015-06-18 12:54:02 +02:00
|
|
|
|
|
|
|
fprintf_ln(stderr, _("There is no tracking information for the current branch."));
|
2015-06-18 12:54:11 +02:00
|
|
|
if (opt_rebase)
|
|
|
|
fprintf_ln(stderr, _("Please specify which branch you want to rebase against."));
|
|
|
|
else
|
|
|
|
fprintf_ln(stderr, _("Please specify which branch you want to merge with."));
|
pull: error on no merge candidates
Commit a8c9bef (pull: improve advice for unconfigured error case,
2009-10-05) fully established the current advices given by git-pull for
the different cases where git-fetch will not have anything marked for
merge:
1. We fetched from a specific remote, and a refspec was given, but it
ended up not fetching anything. This is usually because the user
provided a wildcard refspec which had no matches on the remote end.
2. We fetched from a non-default remote, but didn't specify a branch to
merge. We can't use the configured one because it applies to the
default remote, and thus the user must specify the branches to merge.
3. We fetched from the branch's or repo's default remote, but:
a. We are not on a branch, so there will never be a configured branch
to merge with.
b. We are on a branch, but there is no configured branch to merge
with.
4. We fetched from the branch's or repo's default remote, but the
configured branch to merge didn't get fetched (either it doesn't
exist, or wasn't part of the configured fetch refspec)
Re-implement the above behavior by implementing get_merge_heads() to
parse the heads in FETCH_HEAD for merging, and implementing
die_no_merge_candidates(), which will be called when FETCH_HEAD has no
heads for merging.
Helped-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Helped-by: Junio C Hamano <gitster@pobox.com>
Signed-off-by: Paul Tan <pyokagan@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2015-06-18 12:54:02 +02:00
|
|
|
fprintf_ln(stderr, _("See git-pull(1) for details."));
|
|
|
|
fprintf(stderr, "\n");
|
2016-04-19 15:19:21 +02:00
|
|
|
fprintf_ln(stderr, " git pull %s %s", _("<remote>"), _("<branch>"));
|
pull: error on no merge candidates
Commit a8c9bef (pull: improve advice for unconfigured error case,
2009-10-05) fully established the current advices given by git-pull for
the different cases where git-fetch will not have anything marked for
merge:
1. We fetched from a specific remote, and a refspec was given, but it
ended up not fetching anything. This is usually because the user
provided a wildcard refspec which had no matches on the remote end.
2. We fetched from a non-default remote, but didn't specify a branch to
merge. We can't use the configured one because it applies to the
default remote, and thus the user must specify the branches to merge.
3. We fetched from the branch's or repo's default remote, but:
a. We are not on a branch, so there will never be a configured branch
to merge with.
b. We are on a branch, but there is no configured branch to merge
with.
4. We fetched from the branch's or repo's default remote, but the
configured branch to merge didn't get fetched (either it doesn't
exist, or wasn't part of the configured fetch refspec)
Re-implement the above behavior by implementing get_merge_heads() to
parse the heads in FETCH_HEAD for merging, and implementing
die_no_merge_candidates(), which will be called when FETCH_HEAD has no
heads for merging.
Helped-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Helped-by: Junio C Hamano <gitster@pobox.com>
Signed-off-by: Paul Tan <pyokagan@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2015-06-18 12:54:02 +02:00
|
|
|
fprintf(stderr, "\n");
|
2016-04-19 15:19:22 +02:00
|
|
|
fprintf_ln(stderr, _("If you wish to set tracking information for this branch you can do so with:"));
|
|
|
|
fprintf(stderr, "\n");
|
|
|
|
fprintf_ln(stderr, " git branch --set-upstream-to=%s/%s %s\n",
|
|
|
|
remote_name, _("<branch>"), curr_branch->name);
|
pull: error on no merge candidates
Commit a8c9bef (pull: improve advice for unconfigured error case,
2009-10-05) fully established the current advices given by git-pull for
the different cases where git-fetch will not have anything marked for
merge:
1. We fetched from a specific remote, and a refspec was given, but it
ended up not fetching anything. This is usually because the user
provided a wildcard refspec which had no matches on the remote end.
2. We fetched from a non-default remote, but didn't specify a branch to
merge. We can't use the configured one because it applies to the
default remote, and thus the user must specify the branches to merge.
3. We fetched from the branch's or repo's default remote, but:
a. We are not on a branch, so there will never be a configured branch
to merge with.
b. We are on a branch, but there is no configured branch to merge
with.
4. We fetched from the branch's or repo's default remote, but the
configured branch to merge didn't get fetched (either it doesn't
exist, or wasn't part of the configured fetch refspec)
Re-implement the above behavior by implementing get_merge_heads() to
parse the heads in FETCH_HEAD for merging, and implementing
die_no_merge_candidates(), which will be called when FETCH_HEAD has no
heads for merging.
Helped-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Helped-by: Junio C Hamano <gitster@pobox.com>
Signed-off-by: Paul Tan <pyokagan@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2015-06-18 12:54:02 +02:00
|
|
|
} else
|
|
|
|
fprintf_ln(stderr, _("Your configuration specifies to merge with the ref '%s'\n"
|
|
|
|
"from the remote, but no such ref was fetched."),
|
|
|
|
*curr_branch->merge_name);
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
2015-06-14 10:41:52 +02:00
|
|
|
/**
|
|
|
|
* Parses argv into [<repo> [<refspecs>...]], returning their values in `repo`
|
|
|
|
* as a string and `refspecs` as a null-terminated array of strings. If `repo`
|
|
|
|
* is not provided in argv, it is set to NULL.
|
|
|
|
*/
|
|
|
|
static void parse_repo_refspecs(int argc, const char **argv, const char **repo,
|
|
|
|
const char ***refspecs)
|
|
|
|
{
|
|
|
|
if (argc > 0) {
|
|
|
|
*repo = *argv++;
|
|
|
|
argc--;
|
|
|
|
} else
|
|
|
|
*repo = NULL;
|
|
|
|
*refspecs = argv;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Runs git-fetch, returning its exit status. `repo` and `refspecs` are the
|
|
|
|
* repository and refspecs to fetch, or NULL if they are not provided.
|
|
|
|
*/
|
|
|
|
static int run_fetch(const char *repo, const char **refspecs)
|
|
|
|
{
|
|
|
|
struct argv_array args = ARGV_ARRAY_INIT;
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
argv_array_pushl(&args, "fetch", "--update-head-ok", NULL);
|
2015-06-14 10:41:53 +02:00
|
|
|
|
|
|
|
/* Shared options */
|
|
|
|
argv_push_verbosity(&args);
|
|
|
|
if (opt_progress)
|
|
|
|
argv_array_push(&args, opt_progress);
|
|
|
|
|
2015-06-18 12:54:01 +02:00
|
|
|
/* Options passed to git-fetch */
|
|
|
|
if (opt_all)
|
|
|
|
argv_array_push(&args, opt_all);
|
|
|
|
if (opt_append)
|
|
|
|
argv_array_push(&args, opt_append);
|
|
|
|
if (opt_upload_pack)
|
|
|
|
argv_array_push(&args, opt_upload_pack);
|
|
|
|
argv_push_force(&args);
|
|
|
|
if (opt_tags)
|
|
|
|
argv_array_push(&args, opt_tags);
|
|
|
|
if (opt_prune)
|
|
|
|
argv_array_push(&args, opt_prune);
|
pull: optionally rebase submodules (remote submodule changes only)
Teach pull to optionally update submodules when '--recurse-submodules'
is provided. This will teach pull to run 'submodule update --rebase'
when the '--recurse-submodules' and '--rebase' flags are given under
specific circumstances.
On a rebase workflow:
=====================
1. Both sides change the submodule
------------------------------
Let's assume the following history in a submodule:
H---I---J---K---L local branch
\
M---N---O---P remote branch
and the following in the superproject (recorded submodule in parens):
A(H)---B(I)---F(K)---G(L) local branch
\
C(N)---D(N)---E(P) remote branch
In an ideal world this would rebase the submodule and rewrite
the submodule pointers that the superproject points at such that
the superproject looks like
A(H)---B(I) F(K')---G(L') rebased branch
\ /
C(N)---D(N)---E(P) remote branch
and the submodule as:
J---K---L (old dangeling tip)
/
H---I J'---K'---L' rebased branch
\ /
M---N---O---P remote branch
And if a conflict arises in the submodule the superproject rebase
would stop at that commit at which the submodule conflict occurs.
Currently a "pull --rebase" in the superproject produces
a merge conflict as the submodule pointer changes are
conflicting and cannot be resolved.
2. Local submodule changes only
-----------------------
Assuming histories as above, except that the remote branch
would not contain submodule changes, then a result as
A(H)---B(I) F(K)---G(L) rebased branch
\ /
C(I)---D(I)---E(I) remote branch
is desire-able. This is what currently happens in rebase.
If the recursive flag is given, the ideal git would
produce a superproject as:
A(H)---B(I) F(K')---G(L') rebased branch (incl. sub rebase!)
\ /
C(I)---D(I)---E(I) remote branch
and the submodule as:
J---K---L (old dangeling tip)
/
H---I J'---K'---L' locally rebased branch
\ /
M---N---O---P advanced branch
This patch doesn't address this issue, however
a test is added that this fails up front.
3. Remote submodule changes only
----------------------
Assuming histories as in (1) except that the local superproject branch
would not have touched the submodule the rebase already works out in the
superproject with no conflicts:
A(H)---B(I) F(P)---G(P) rebased branch (no sub changes)
\ /
C(N)---D(N)---E(P) remote branch
The recurse flag as presented in this patch would additionally
update the submodule as:
H---I J'---K'---L' rebased branch
\ /
M---N---O---P remote branch
As neither J, K, L nor J', K', L' are referred to from the superproject,
no rewriting of the superproject commits is required.
Conclusion for 'pull --rebase --recursive'
-----------------------------------------
If there are no local superproject changes it is sufficient to call
"submodule update --rebase" as this produces the desired results. In case
of conflicts, the behavior is the same as in 'submodule update --recursive'
which is assumed to be sane.
This patch implements (3) only.
On a merge workflow:
====================
We'll start off with the same underlying DAG as in (1) in the rebase
workflow. So in an ideal world a 'pull --merge --recursive' would
produce this:
H---I---J---K---L----X
\ /
M---N---O---P
with X as the new merge-commit in the submodule and the superproject
as:
A(H)---B(I)---F(K)---G(L)---Y(X)
\ /
C(N)---D(N)---E(P)
However modifying the submodules on the fly is not supported in git-merge
such that Y(X) is not easy to produce in a single patch. In fact git-merge
doesn't know about submodules at all.
However when at least one side does not contain commits touching the
submodule at all, then we do not need to perform the merge for the
submodule but a fast-forward can be done via checking out either L or P
in the submodule. This strategy is implemented in 68d03e4a6e (Implement
automatic fast-forward merge for submodules, 2010-07-07) already, so
to align with the rebase behavior we need to also update the worktree
of the submodule.
Signed-off-by: Brandon Williams <bmwill@google.com>
Signed-off-by: Stefan Beller <sbeller@google.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-06-23 21:13:02 +02:00
|
|
|
if (recurse_submodules != RECURSE_SUBMODULES_DEFAULT)
|
|
|
|
switch (recurse_submodules) {
|
|
|
|
case RECURSE_SUBMODULES_ON:
|
|
|
|
argv_array_push(&args, "--recurse-submodules=on");
|
|
|
|
break;
|
|
|
|
case RECURSE_SUBMODULES_OFF:
|
|
|
|
argv_array_push(&args, "--recurse-submodules=no");
|
|
|
|
break;
|
|
|
|
case RECURSE_SUBMODULES_ON_DEMAND:
|
|
|
|
argv_array_push(&args, "--recurse-submodules=on-demand");
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
BUG("submodule recursion option not understood");
|
|
|
|
}
|
2015-12-16 01:04:12 +01:00
|
|
|
if (max_children)
|
|
|
|
argv_array_push(&args, max_children);
|
2015-06-18 12:54:01 +02:00
|
|
|
if (opt_dry_run)
|
|
|
|
argv_array_push(&args, "--dry-run");
|
|
|
|
if (opt_keep)
|
|
|
|
argv_array_push(&args, opt_keep);
|
|
|
|
if (opt_depth)
|
|
|
|
argv_array_push(&args, opt_depth);
|
|
|
|
if (opt_unshallow)
|
|
|
|
argv_array_push(&args, opt_unshallow);
|
|
|
|
if (opt_update_shallow)
|
|
|
|
argv_array_push(&args, opt_update_shallow);
|
|
|
|
if (opt_refmap)
|
|
|
|
argv_array_push(&args, opt_refmap);
|
|
|
|
|
2015-06-14 10:41:52 +02:00
|
|
|
if (repo) {
|
|
|
|
argv_array_push(&args, repo);
|
|
|
|
argv_array_pushv(&args, refspecs);
|
|
|
|
} else if (*refspecs)
|
|
|
|
die("BUG: refspecs without repo?");
|
|
|
|
ret = run_command_v_opt(args.argv, RUN_GIT_CMD);
|
|
|
|
argv_array_clear(&args);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2015-06-18 12:54:06 +02:00
|
|
|
/**
|
|
|
|
* "Pulls into void" by branching off merge_head.
|
|
|
|
*/
|
2017-03-26 18:01:37 +02:00
|
|
|
static int pull_into_void(const struct object_id *merge_head,
|
2017-03-26 18:01:36 +02:00
|
|
|
const struct object_id *curr_head)
|
2015-06-18 12:54:06 +02:00
|
|
|
{
|
|
|
|
/*
|
|
|
|
* Two-way merge: we treat the index as 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.
|
|
|
|
*/
|
2017-05-07 00:10:33 +02:00
|
|
|
if (checkout_fast_forward(&empty_tree_oid, merge_head, 0))
|
2015-06-18 12:54:06 +02:00
|
|
|
return 1;
|
|
|
|
|
2017-03-26 18:01:37 +02:00
|
|
|
if (update_ref("initial pull", "HEAD", merge_head->hash, curr_head->hash, 0, UPDATE_REFS_DIE_ON_ERR))
|
2015-06-18 12:54:06 +02:00
|
|
|
return 1;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
pull: optionally rebase submodules (remote submodule changes only)
Teach pull to optionally update submodules when '--recurse-submodules'
is provided. This will teach pull to run 'submodule update --rebase'
when the '--recurse-submodules' and '--rebase' flags are given under
specific circumstances.
On a rebase workflow:
=====================
1. Both sides change the submodule
------------------------------
Let's assume the following history in a submodule:
H---I---J---K---L local branch
\
M---N---O---P remote branch
and the following in the superproject (recorded submodule in parens):
A(H)---B(I)---F(K)---G(L) local branch
\
C(N)---D(N)---E(P) remote branch
In an ideal world this would rebase the submodule and rewrite
the submodule pointers that the superproject points at such that
the superproject looks like
A(H)---B(I) F(K')---G(L') rebased branch
\ /
C(N)---D(N)---E(P) remote branch
and the submodule as:
J---K---L (old dangeling tip)
/
H---I J'---K'---L' rebased branch
\ /
M---N---O---P remote branch
And if a conflict arises in the submodule the superproject rebase
would stop at that commit at which the submodule conflict occurs.
Currently a "pull --rebase" in the superproject produces
a merge conflict as the submodule pointer changes are
conflicting and cannot be resolved.
2. Local submodule changes only
-----------------------
Assuming histories as above, except that the remote branch
would not contain submodule changes, then a result as
A(H)---B(I) F(K)---G(L) rebased branch
\ /
C(I)---D(I)---E(I) remote branch
is desire-able. This is what currently happens in rebase.
If the recursive flag is given, the ideal git would
produce a superproject as:
A(H)---B(I) F(K')---G(L') rebased branch (incl. sub rebase!)
\ /
C(I)---D(I)---E(I) remote branch
and the submodule as:
J---K---L (old dangeling tip)
/
H---I J'---K'---L' locally rebased branch
\ /
M---N---O---P advanced branch
This patch doesn't address this issue, however
a test is added that this fails up front.
3. Remote submodule changes only
----------------------
Assuming histories as in (1) except that the local superproject branch
would not have touched the submodule the rebase already works out in the
superproject with no conflicts:
A(H)---B(I) F(P)---G(P) rebased branch (no sub changes)
\ /
C(N)---D(N)---E(P) remote branch
The recurse flag as presented in this patch would additionally
update the submodule as:
H---I J'---K'---L' rebased branch
\ /
M---N---O---P remote branch
As neither J, K, L nor J', K', L' are referred to from the superproject,
no rewriting of the superproject commits is required.
Conclusion for 'pull --rebase --recursive'
-----------------------------------------
If there are no local superproject changes it is sufficient to call
"submodule update --rebase" as this produces the desired results. In case
of conflicts, the behavior is the same as in 'submodule update --recursive'
which is assumed to be sane.
This patch implements (3) only.
On a merge workflow:
====================
We'll start off with the same underlying DAG as in (1) in the rebase
workflow. So in an ideal world a 'pull --merge --recursive' would
produce this:
H---I---J---K---L----X
\ /
M---N---O---P
with X as the new merge-commit in the submodule and the superproject
as:
A(H)---B(I)---F(K)---G(L)---Y(X)
\ /
C(N)---D(N)---E(P)
However modifying the submodules on the fly is not supported in git-merge
such that Y(X) is not easy to produce in a single patch. In fact git-merge
doesn't know about submodules at all.
However when at least one side does not contain commits touching the
submodule at all, then we do not need to perform the merge for the
submodule but a fast-forward can be done via checking out either L or P
in the submodule. This strategy is implemented in 68d03e4a6e (Implement
automatic fast-forward merge for submodules, 2010-07-07) already, so
to align with the rebase behavior we need to also update the worktree
of the submodule.
Signed-off-by: Brandon Williams <bmwill@google.com>
Signed-off-by: Stefan Beller <sbeller@google.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-06-23 21:13:02 +02:00
|
|
|
static int rebase_submodules(void)
|
|
|
|
{
|
|
|
|
struct child_process cp = CHILD_PROCESS_INIT;
|
|
|
|
|
|
|
|
cp.git_cmd = 1;
|
|
|
|
cp.no_stdin = 1;
|
|
|
|
argv_array_pushl(&cp.args, "submodule", "update",
|
|
|
|
"--recursive", "--rebase", NULL);
|
|
|
|
|
|
|
|
return run_command(&cp);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int update_submodules(void)
|
|
|
|
{
|
|
|
|
struct child_process cp = CHILD_PROCESS_INIT;
|
|
|
|
|
|
|
|
cp.git_cmd = 1;
|
|
|
|
cp.no_stdin = 1;
|
|
|
|
argv_array_pushl(&cp.args, "submodule", "update",
|
|
|
|
"--recursive", "--checkout", NULL);
|
|
|
|
|
|
|
|
return run_command(&cp);
|
|
|
|
}
|
|
|
|
|
2015-06-14 10:41:52 +02:00
|
|
|
/**
|
|
|
|
* Runs git-merge, returning its exit status.
|
|
|
|
*/
|
|
|
|
static int run_merge(void)
|
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
struct argv_array args = ARGV_ARRAY_INIT;
|
|
|
|
|
|
|
|
argv_array_pushl(&args, "merge", NULL);
|
2015-06-14 10:41:53 +02:00
|
|
|
|
|
|
|
/* Shared options */
|
|
|
|
argv_push_verbosity(&args);
|
|
|
|
if (opt_progress)
|
|
|
|
argv_array_push(&args, opt_progress);
|
|
|
|
|
pull: pass git-merge's options to git-merge
Specify git-merge's options in the option list, and pass any specified
options to git-merge.
These options are:
* -n, --stat, --summary: since d8abe14 (merge, pull: introduce
'--(no-)stat' option, 2008-04-06)
* --log: since efb779f (merge, pull: add '--(no-)log' command line
option, 2008-04-06)
* --squash: since 7d0c688 (git-merge --squash, 2006-06-23)
* --commit: since 5072a32 (Teach git-pull about --[no-]ff, --no-squash
and --commit, 2007-10-29)
* --edit: since 8580830 ("git pull" doesn't know "--edit", 2012-02-11)
* --ff, --ff-only: since 5072a32 (Teach git-pull about --[no-]ff,
--no-squash and --commit, 2007-10-29)
* --verify-signatures: since efed002 (merge/pull: verify GPG signatures
of commits being merged, 2013-03-31)
* -s, --strategy: since 60fb5b2 (Use git-merge in git-pull (second
try)., 2005-09-25)
* -X, --strategy-option: since ee2c795 (Teach git-pull to pass
-X<option> to git-merge, 2009-11-25)
* -S, --gpg-sign: since ea230d8 (pull: add the --gpg-sign option.,
2014-02-10)
Signed-off-by: Paul Tan <pyokagan@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2015-06-14 10:41:54 +02:00
|
|
|
/* Options passed to git-merge */
|
|
|
|
if (opt_diffstat)
|
|
|
|
argv_array_push(&args, opt_diffstat);
|
|
|
|
if (opt_log)
|
|
|
|
argv_array_push(&args, opt_log);
|
|
|
|
if (opt_squash)
|
|
|
|
argv_array_push(&args, opt_squash);
|
|
|
|
if (opt_commit)
|
|
|
|
argv_array_push(&args, opt_commit);
|
|
|
|
if (opt_edit)
|
|
|
|
argv_array_push(&args, opt_edit);
|
|
|
|
if (opt_ff)
|
|
|
|
argv_array_push(&args, opt_ff);
|
|
|
|
if (opt_verify_signatures)
|
|
|
|
argv_array_push(&args, opt_verify_signatures);
|
|
|
|
argv_array_pushv(&args, opt_strategies.argv);
|
|
|
|
argv_array_pushv(&args, opt_strategy_opts.argv);
|
|
|
|
if (opt_gpg_sign)
|
|
|
|
argv_array_push(&args, opt_gpg_sign);
|
2016-03-18 21:21:09 +01:00
|
|
|
if (opt_allow_unrelated_histories > 0)
|
|
|
|
argv_array_push(&args, "--allow-unrelated-histories");
|
pull: pass git-merge's options to git-merge
Specify git-merge's options in the option list, and pass any specified
options to git-merge.
These options are:
* -n, --stat, --summary: since d8abe14 (merge, pull: introduce
'--(no-)stat' option, 2008-04-06)
* --log: since efb779f (merge, pull: add '--(no-)log' command line
option, 2008-04-06)
* --squash: since 7d0c688 (git-merge --squash, 2006-06-23)
* --commit: since 5072a32 (Teach git-pull about --[no-]ff, --no-squash
and --commit, 2007-10-29)
* --edit: since 8580830 ("git pull" doesn't know "--edit", 2012-02-11)
* --ff, --ff-only: since 5072a32 (Teach git-pull about --[no-]ff,
--no-squash and --commit, 2007-10-29)
* --verify-signatures: since efed002 (merge/pull: verify GPG signatures
of commits being merged, 2013-03-31)
* -s, --strategy: since 60fb5b2 (Use git-merge in git-pull (second
try)., 2005-09-25)
* -X, --strategy-option: since ee2c795 (Teach git-pull to pass
-X<option> to git-merge, 2009-11-25)
* -S, --gpg-sign: since ea230d8 (pull: add the --gpg-sign option.,
2014-02-10)
Signed-off-by: Paul Tan <pyokagan@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2015-06-14 10:41:54 +02:00
|
|
|
|
2015-06-14 10:41:52 +02:00
|
|
|
argv_array_push(&args, "FETCH_HEAD");
|
|
|
|
ret = run_command_v_opt(args.argv, RUN_GIT_CMD);
|
|
|
|
argv_array_clear(&args);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
pull: teach git pull about --rebase
Since cd67e4d (Teach 'git pull' about --rebase, 2007-11-28), if the
--rebase option is set, git-rebase is run instead of git-merge.
Re-implement this by introducing run_rebase(), which is called instead
of run_merge() if opt_rebase is a true value.
Since c85c792 (pull --rebase: be cleverer with rebased upstream
branches, 2008-01-26), git-pull handles the case where the upstream
branch was rebased since it was last fetched. The fork point (old remote
ref) of the branch from the upstream branch is calculated before fetch,
and then rebased from onto the new remote head (merge_head) after fetch.
Re-implement this by introducing get_merge_branch_2() and
get_merge_branch_1() to find the upstream branch for the
specified/current branch, and get_rebase_fork_point() which will find
the fork point between the upstream branch and current branch.
However, the above change created a problem where git-rebase cannot
detect commits that are already upstream, and thus may result in
unnecessary conflicts. cf65426 (pull --rebase: Avoid spurious conflicts
and reapplying unnecessary patches, 2010-08-12) fixes this by ignoring
the above old remote ref if it is contained within the merge base of the
merge head and the current branch.
This is re-implemented in run_rebase() where fork_point is not used if
it is the merge base returned by get_octopus_merge_base().
Helped-by: Stefan Beller <sbeller@google.com>
Helped-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Paul Tan <pyokagan@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2015-06-18 12:54:08 +02:00
|
|
|
/**
|
|
|
|
* Returns remote's upstream branch for the current branch. If remote is NULL,
|
|
|
|
* the current branch's configured default remote is used. Returns NULL if
|
|
|
|
* `remote` does not name a valid remote, HEAD does not point to a branch,
|
|
|
|
* remote is not the branch's configured remote or the branch does not have any
|
|
|
|
* configured upstream branch.
|
|
|
|
*/
|
|
|
|
static const char *get_upstream_branch(const char *remote)
|
|
|
|
{
|
|
|
|
struct remote *rm;
|
|
|
|
struct branch *curr_branch;
|
|
|
|
const char *curr_branch_remote;
|
|
|
|
|
|
|
|
rm = remote_get(remote);
|
|
|
|
if (!rm)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
curr_branch = branch_get("HEAD");
|
|
|
|
if (!curr_branch)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
curr_branch_remote = remote_for_branch(curr_branch, NULL);
|
|
|
|
assert(curr_branch_remote);
|
|
|
|
|
|
|
|
if (strcmp(curr_branch_remote, rm->name))
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
return branch_get_upstream(curr_branch, NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Derives the remote tracking branch from the remote and refspec.
|
|
|
|
*
|
|
|
|
* FIXME: The current implementation assumes the default mapping of
|
|
|
|
* refs/heads/<branch_name> to refs/remotes/<remote_name>/<branch_name>.
|
|
|
|
*/
|
|
|
|
static const char *get_tracking_branch(const char *remote, const char *refspec)
|
|
|
|
{
|
|
|
|
struct refspec *spec;
|
|
|
|
const char *spec_src;
|
|
|
|
const char *merge_branch;
|
|
|
|
|
|
|
|
spec = parse_fetch_refspec(1, &refspec);
|
|
|
|
spec_src = spec->src;
|
|
|
|
if (!*spec_src || !strcmp(spec_src, "HEAD"))
|
|
|
|
spec_src = "HEAD";
|
|
|
|
else if (skip_prefix(spec_src, "heads/", &spec_src))
|
|
|
|
;
|
|
|
|
else if (skip_prefix(spec_src, "refs/heads/", &spec_src))
|
|
|
|
;
|
|
|
|
else if (starts_with(spec_src, "refs/") ||
|
|
|
|
starts_with(spec_src, "tags/") ||
|
|
|
|
starts_with(spec_src, "remotes/"))
|
|
|
|
spec_src = "";
|
|
|
|
|
|
|
|
if (*spec_src) {
|
|
|
|
if (!strcmp(remote, "."))
|
|
|
|
merge_branch = mkpath("refs/heads/%s", spec_src);
|
|
|
|
else
|
|
|
|
merge_branch = mkpath("refs/remotes/%s/%s", remote, spec_src);
|
|
|
|
} else
|
|
|
|
merge_branch = NULL;
|
|
|
|
|
|
|
|
free_refspec(1, spec);
|
|
|
|
return merge_branch;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Given the repo and refspecs, sets fork_point to the point at which the
|
|
|
|
* current branch forked from its remote tracking branch. Returns 0 on success,
|
|
|
|
* -1 on failure.
|
|
|
|
*/
|
2017-03-26 18:01:36 +02:00
|
|
|
static int get_rebase_fork_point(struct object_id *fork_point, const char *repo,
|
pull: teach git pull about --rebase
Since cd67e4d (Teach 'git pull' about --rebase, 2007-11-28), if the
--rebase option is set, git-rebase is run instead of git-merge.
Re-implement this by introducing run_rebase(), which is called instead
of run_merge() if opt_rebase is a true value.
Since c85c792 (pull --rebase: be cleverer with rebased upstream
branches, 2008-01-26), git-pull handles the case where the upstream
branch was rebased since it was last fetched. The fork point (old remote
ref) of the branch from the upstream branch is calculated before fetch,
and then rebased from onto the new remote head (merge_head) after fetch.
Re-implement this by introducing get_merge_branch_2() and
get_merge_branch_1() to find the upstream branch for the
specified/current branch, and get_rebase_fork_point() which will find
the fork point between the upstream branch and current branch.
However, the above change created a problem where git-rebase cannot
detect commits that are already upstream, and thus may result in
unnecessary conflicts. cf65426 (pull --rebase: Avoid spurious conflicts
and reapplying unnecessary patches, 2010-08-12) fixes this by ignoring
the above old remote ref if it is contained within the merge base of the
merge head and the current branch.
This is re-implemented in run_rebase() where fork_point is not used if
it is the merge base returned by get_octopus_merge_base().
Helped-by: Stefan Beller <sbeller@google.com>
Helped-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Paul Tan <pyokagan@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2015-06-18 12:54:08 +02:00
|
|
|
const char *refspec)
|
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
struct branch *curr_branch;
|
|
|
|
const char *remote_branch;
|
|
|
|
struct child_process cp = CHILD_PROCESS_INIT;
|
|
|
|
struct strbuf sb = STRBUF_INIT;
|
|
|
|
|
|
|
|
curr_branch = branch_get("HEAD");
|
|
|
|
if (!curr_branch)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
if (refspec)
|
|
|
|
remote_branch = get_tracking_branch(repo, refspec);
|
|
|
|
else
|
|
|
|
remote_branch = get_upstream_branch(repo);
|
|
|
|
|
|
|
|
if (!remote_branch)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
argv_array_pushl(&cp.args, "merge-base", "--fork-point",
|
|
|
|
remote_branch, curr_branch->name, NULL);
|
|
|
|
cp.no_stdin = 1;
|
|
|
|
cp.no_stderr = 1;
|
|
|
|
cp.git_cmd = 1;
|
|
|
|
|
|
|
|
ret = capture_command(&cp, &sb, GIT_SHA1_HEXSZ);
|
|
|
|
if (ret)
|
|
|
|
goto cleanup;
|
|
|
|
|
2017-03-26 18:01:36 +02:00
|
|
|
ret = get_oid_hex(sb.buf, fork_point);
|
pull: teach git pull about --rebase
Since cd67e4d (Teach 'git pull' about --rebase, 2007-11-28), if the
--rebase option is set, git-rebase is run instead of git-merge.
Re-implement this by introducing run_rebase(), which is called instead
of run_merge() if opt_rebase is a true value.
Since c85c792 (pull --rebase: be cleverer with rebased upstream
branches, 2008-01-26), git-pull handles the case where the upstream
branch was rebased since it was last fetched. The fork point (old remote
ref) of the branch from the upstream branch is calculated before fetch,
and then rebased from onto the new remote head (merge_head) after fetch.
Re-implement this by introducing get_merge_branch_2() and
get_merge_branch_1() to find the upstream branch for the
specified/current branch, and get_rebase_fork_point() which will find
the fork point between the upstream branch and current branch.
However, the above change created a problem where git-rebase cannot
detect commits that are already upstream, and thus may result in
unnecessary conflicts. cf65426 (pull --rebase: Avoid spurious conflicts
and reapplying unnecessary patches, 2010-08-12) fixes this by ignoring
the above old remote ref if it is contained within the merge base of the
merge head and the current branch.
This is re-implemented in run_rebase() where fork_point is not used if
it is the merge base returned by get_octopus_merge_base().
Helped-by: Stefan Beller <sbeller@google.com>
Helped-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Paul Tan <pyokagan@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2015-06-18 12:54:08 +02:00
|
|
|
if (ret)
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
strbuf_release(&sb);
|
|
|
|
return ret ? -1 : 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Sets merge_base to the octopus merge base of curr_head, merge_head and
|
|
|
|
* fork_point. Returns 0 if a merge base is found, 1 otherwise.
|
|
|
|
*/
|
2017-03-26 18:01:36 +02:00
|
|
|
static int get_octopus_merge_base(struct object_id *merge_base,
|
|
|
|
const struct object_id *curr_head,
|
2017-03-26 18:01:37 +02:00
|
|
|
const struct object_id *merge_head,
|
2017-03-26 18:01:36 +02:00
|
|
|
const struct object_id *fork_point)
|
pull: teach git pull about --rebase
Since cd67e4d (Teach 'git pull' about --rebase, 2007-11-28), if the
--rebase option is set, git-rebase is run instead of git-merge.
Re-implement this by introducing run_rebase(), which is called instead
of run_merge() if opt_rebase is a true value.
Since c85c792 (pull --rebase: be cleverer with rebased upstream
branches, 2008-01-26), git-pull handles the case where the upstream
branch was rebased since it was last fetched. The fork point (old remote
ref) of the branch from the upstream branch is calculated before fetch,
and then rebased from onto the new remote head (merge_head) after fetch.
Re-implement this by introducing get_merge_branch_2() and
get_merge_branch_1() to find the upstream branch for the
specified/current branch, and get_rebase_fork_point() which will find
the fork point between the upstream branch and current branch.
However, the above change created a problem where git-rebase cannot
detect commits that are already upstream, and thus may result in
unnecessary conflicts. cf65426 (pull --rebase: Avoid spurious conflicts
and reapplying unnecessary patches, 2010-08-12) fixes this by ignoring
the above old remote ref if it is contained within the merge base of the
merge head and the current branch.
This is re-implemented in run_rebase() where fork_point is not used if
it is the merge base returned by get_octopus_merge_base().
Helped-by: Stefan Beller <sbeller@google.com>
Helped-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Paul Tan <pyokagan@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2015-06-18 12:54:08 +02:00
|
|
|
{
|
|
|
|
struct commit_list *revs = NULL, *result;
|
|
|
|
|
Convert lookup_commit* to struct object_id
Convert lookup_commit, lookup_commit_or_die,
lookup_commit_reference, and lookup_commit_reference_gently to take
struct object_id arguments.
Introduce a temporary in parse_object buffer in order to convert this
function. This is required since in order to convert parse_object and
parse_object_buffer, lookup_commit_reference_gently and
lookup_commit_or_die would need to be converted. Not introducing a
temporary would therefore require that lookup_commit_or_die take a
struct object_id *, but lookup_commit would take unsigned char *,
leaving a confusing and hard-to-use interface.
parse_object_buffer will lose this temporary in a later patch.
This commit was created with manual changes to commit.c, commit.h, and
object.c, plus the following semantic patch:
@@
expression E1, E2;
@@
- lookup_commit_reference_gently(E1.hash, E2)
+ lookup_commit_reference_gently(&E1, E2)
@@
expression E1, E2;
@@
- lookup_commit_reference_gently(E1->hash, E2)
+ lookup_commit_reference_gently(E1, E2)
@@
expression E1;
@@
- lookup_commit_reference(E1.hash)
+ lookup_commit_reference(&E1)
@@
expression E1;
@@
- lookup_commit_reference(E1->hash)
+ lookup_commit_reference(E1)
@@
expression E1;
@@
- lookup_commit(E1.hash)
+ lookup_commit(&E1)
@@
expression E1;
@@
- lookup_commit(E1->hash)
+ lookup_commit(E1)
@@
expression E1, E2;
@@
- lookup_commit_or_die(E1.hash, E2)
+ lookup_commit_or_die(&E1, E2)
@@
expression E1, E2;
@@
- lookup_commit_or_die(E1->hash, E2)
+ lookup_commit_or_die(E1, E2)
Signed-off-by: brian m. carlson <sandals@crustytoothpaste.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-05-07 00:10:10 +02:00
|
|
|
commit_list_insert(lookup_commit_reference(curr_head), &revs);
|
|
|
|
commit_list_insert(lookup_commit_reference(merge_head), &revs);
|
2017-03-26 18:01:36 +02:00
|
|
|
if (!is_null_oid(fork_point))
|
Convert lookup_commit* to struct object_id
Convert lookup_commit, lookup_commit_or_die,
lookup_commit_reference, and lookup_commit_reference_gently to take
struct object_id arguments.
Introduce a temporary in parse_object buffer in order to convert this
function. This is required since in order to convert parse_object and
parse_object_buffer, lookup_commit_reference_gently and
lookup_commit_or_die would need to be converted. Not introducing a
temporary would therefore require that lookup_commit_or_die take a
struct object_id *, but lookup_commit would take unsigned char *,
leaving a confusing and hard-to-use interface.
parse_object_buffer will lose this temporary in a later patch.
This commit was created with manual changes to commit.c, commit.h, and
object.c, plus the following semantic patch:
@@
expression E1, E2;
@@
- lookup_commit_reference_gently(E1.hash, E2)
+ lookup_commit_reference_gently(&E1, E2)
@@
expression E1, E2;
@@
- lookup_commit_reference_gently(E1->hash, E2)
+ lookup_commit_reference_gently(E1, E2)
@@
expression E1;
@@
- lookup_commit_reference(E1.hash)
+ lookup_commit_reference(&E1)
@@
expression E1;
@@
- lookup_commit_reference(E1->hash)
+ lookup_commit_reference(E1)
@@
expression E1;
@@
- lookup_commit(E1.hash)
+ lookup_commit(&E1)
@@
expression E1;
@@
- lookup_commit(E1->hash)
+ lookup_commit(E1)
@@
expression E1, E2;
@@
- lookup_commit_or_die(E1.hash, E2)
+ lookup_commit_or_die(&E1, E2)
@@
expression E1, E2;
@@
- lookup_commit_or_die(E1->hash, E2)
+ lookup_commit_or_die(E1, E2)
Signed-off-by: brian m. carlson <sandals@crustytoothpaste.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-05-07 00:10:10 +02:00
|
|
|
commit_list_insert(lookup_commit_reference(fork_point), &revs);
|
pull: teach git pull about --rebase
Since cd67e4d (Teach 'git pull' about --rebase, 2007-11-28), if the
--rebase option is set, git-rebase is run instead of git-merge.
Re-implement this by introducing run_rebase(), which is called instead
of run_merge() if opt_rebase is a true value.
Since c85c792 (pull --rebase: be cleverer with rebased upstream
branches, 2008-01-26), git-pull handles the case where the upstream
branch was rebased since it was last fetched. The fork point (old remote
ref) of the branch from the upstream branch is calculated before fetch,
and then rebased from onto the new remote head (merge_head) after fetch.
Re-implement this by introducing get_merge_branch_2() and
get_merge_branch_1() to find the upstream branch for the
specified/current branch, and get_rebase_fork_point() which will find
the fork point between the upstream branch and current branch.
However, the above change created a problem where git-rebase cannot
detect commits that are already upstream, and thus may result in
unnecessary conflicts. cf65426 (pull --rebase: Avoid spurious conflicts
and reapplying unnecessary patches, 2010-08-12) fixes this by ignoring
the above old remote ref if it is contained within the merge base of the
merge head and the current branch.
This is re-implemented in run_rebase() where fork_point is not used if
it is the merge base returned by get_octopus_merge_base().
Helped-by: Stefan Beller <sbeller@google.com>
Helped-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Paul Tan <pyokagan@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2015-06-18 12:54:08 +02:00
|
|
|
|
|
|
|
result = reduce_heads(get_octopus_merge_bases(revs));
|
|
|
|
free_commit_list(revs);
|
|
|
|
if (!result)
|
|
|
|
return 1;
|
|
|
|
|
2017-03-26 18:01:36 +02:00
|
|
|
oidcpy(merge_base, &result->item->object.oid);
|
pull: teach git pull about --rebase
Since cd67e4d (Teach 'git pull' about --rebase, 2007-11-28), if the
--rebase option is set, git-rebase is run instead of git-merge.
Re-implement this by introducing run_rebase(), which is called instead
of run_merge() if opt_rebase is a true value.
Since c85c792 (pull --rebase: be cleverer with rebased upstream
branches, 2008-01-26), git-pull handles the case where the upstream
branch was rebased since it was last fetched. The fork point (old remote
ref) of the branch from the upstream branch is calculated before fetch,
and then rebased from onto the new remote head (merge_head) after fetch.
Re-implement this by introducing get_merge_branch_2() and
get_merge_branch_1() to find the upstream branch for the
specified/current branch, and get_rebase_fork_point() which will find
the fork point between the upstream branch and current branch.
However, the above change created a problem where git-rebase cannot
detect commits that are already upstream, and thus may result in
unnecessary conflicts. cf65426 (pull --rebase: Avoid spurious conflicts
and reapplying unnecessary patches, 2010-08-12) fixes this by ignoring
the above old remote ref if it is contained within the merge base of the
merge head and the current branch.
This is re-implemented in run_rebase() where fork_point is not used if
it is the merge base returned by get_octopus_merge_base().
Helped-by: Stefan Beller <sbeller@google.com>
Helped-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Paul Tan <pyokagan@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2015-06-18 12:54:08 +02:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Given the current HEAD SHA1, the merge head returned from git-fetch and the
|
|
|
|
* fork point calculated by get_rebase_fork_point(), runs git-rebase with the
|
|
|
|
* appropriate arguments and returns its exit status.
|
|
|
|
*/
|
2017-03-26 18:01:36 +02:00
|
|
|
static int run_rebase(const struct object_id *curr_head,
|
2017-03-26 18:01:37 +02:00
|
|
|
const struct object_id *merge_head,
|
2017-03-26 18:01:36 +02:00
|
|
|
const struct object_id *fork_point)
|
pull: teach git pull about --rebase
Since cd67e4d (Teach 'git pull' about --rebase, 2007-11-28), if the
--rebase option is set, git-rebase is run instead of git-merge.
Re-implement this by introducing run_rebase(), which is called instead
of run_merge() if opt_rebase is a true value.
Since c85c792 (pull --rebase: be cleverer with rebased upstream
branches, 2008-01-26), git-pull handles the case where the upstream
branch was rebased since it was last fetched. The fork point (old remote
ref) of the branch from the upstream branch is calculated before fetch,
and then rebased from onto the new remote head (merge_head) after fetch.
Re-implement this by introducing get_merge_branch_2() and
get_merge_branch_1() to find the upstream branch for the
specified/current branch, and get_rebase_fork_point() which will find
the fork point between the upstream branch and current branch.
However, the above change created a problem where git-rebase cannot
detect commits that are already upstream, and thus may result in
unnecessary conflicts. cf65426 (pull --rebase: Avoid spurious conflicts
and reapplying unnecessary patches, 2010-08-12) fixes this by ignoring
the above old remote ref if it is contained within the merge base of the
merge head and the current branch.
This is re-implemented in run_rebase() where fork_point is not used if
it is the merge base returned by get_octopus_merge_base().
Helped-by: Stefan Beller <sbeller@google.com>
Helped-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Paul Tan <pyokagan@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2015-06-18 12:54:08 +02:00
|
|
|
{
|
|
|
|
int ret;
|
2017-03-26 18:01:36 +02:00
|
|
|
struct object_id oct_merge_base;
|
pull: teach git pull about --rebase
Since cd67e4d (Teach 'git pull' about --rebase, 2007-11-28), if the
--rebase option is set, git-rebase is run instead of git-merge.
Re-implement this by introducing run_rebase(), which is called instead
of run_merge() if opt_rebase is a true value.
Since c85c792 (pull --rebase: be cleverer with rebased upstream
branches, 2008-01-26), git-pull handles the case where the upstream
branch was rebased since it was last fetched. The fork point (old remote
ref) of the branch from the upstream branch is calculated before fetch,
and then rebased from onto the new remote head (merge_head) after fetch.
Re-implement this by introducing get_merge_branch_2() and
get_merge_branch_1() to find the upstream branch for the
specified/current branch, and get_rebase_fork_point() which will find
the fork point between the upstream branch and current branch.
However, the above change created a problem where git-rebase cannot
detect commits that are already upstream, and thus may result in
unnecessary conflicts. cf65426 (pull --rebase: Avoid spurious conflicts
and reapplying unnecessary patches, 2010-08-12) fixes this by ignoring
the above old remote ref if it is contained within the merge base of the
merge head and the current branch.
This is re-implemented in run_rebase() where fork_point is not used if
it is the merge base returned by get_octopus_merge_base().
Helped-by: Stefan Beller <sbeller@google.com>
Helped-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Paul Tan <pyokagan@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2015-06-18 12:54:08 +02:00
|
|
|
struct argv_array args = ARGV_ARRAY_INIT;
|
|
|
|
|
2017-03-26 18:01:36 +02:00
|
|
|
if (!get_octopus_merge_base(&oct_merge_base, curr_head, merge_head, fork_point))
|
|
|
|
if (!is_null_oid(fork_point) && !oidcmp(&oct_merge_base, fork_point))
|
pull: teach git pull about --rebase
Since cd67e4d (Teach 'git pull' about --rebase, 2007-11-28), if the
--rebase option is set, git-rebase is run instead of git-merge.
Re-implement this by introducing run_rebase(), which is called instead
of run_merge() if opt_rebase is a true value.
Since c85c792 (pull --rebase: be cleverer with rebased upstream
branches, 2008-01-26), git-pull handles the case where the upstream
branch was rebased since it was last fetched. The fork point (old remote
ref) of the branch from the upstream branch is calculated before fetch,
and then rebased from onto the new remote head (merge_head) after fetch.
Re-implement this by introducing get_merge_branch_2() and
get_merge_branch_1() to find the upstream branch for the
specified/current branch, and get_rebase_fork_point() which will find
the fork point between the upstream branch and current branch.
However, the above change created a problem where git-rebase cannot
detect commits that are already upstream, and thus may result in
unnecessary conflicts. cf65426 (pull --rebase: Avoid spurious conflicts
and reapplying unnecessary patches, 2010-08-12) fixes this by ignoring
the above old remote ref if it is contained within the merge base of the
merge head and the current branch.
This is re-implemented in run_rebase() where fork_point is not used if
it is the merge base returned by get_octopus_merge_base().
Helped-by: Stefan Beller <sbeller@google.com>
Helped-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Paul Tan <pyokagan@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2015-06-18 12:54:08 +02:00
|
|
|
fork_point = NULL;
|
|
|
|
|
|
|
|
argv_array_push(&args, "rebase");
|
|
|
|
|
|
|
|
/* Shared options */
|
|
|
|
argv_push_verbosity(&args);
|
|
|
|
|
|
|
|
/* Options passed to git-rebase */
|
|
|
|
if (opt_rebase == REBASE_PRESERVE)
|
|
|
|
argv_array_push(&args, "--preserve-merges");
|
2016-01-13 13:17:15 +01:00
|
|
|
else if (opt_rebase == REBASE_INTERACTIVE)
|
|
|
|
argv_array_push(&args, "--interactive");
|
pull: teach git pull about --rebase
Since cd67e4d (Teach 'git pull' about --rebase, 2007-11-28), if the
--rebase option is set, git-rebase is run instead of git-merge.
Re-implement this by introducing run_rebase(), which is called instead
of run_merge() if opt_rebase is a true value.
Since c85c792 (pull --rebase: be cleverer with rebased upstream
branches, 2008-01-26), git-pull handles the case where the upstream
branch was rebased since it was last fetched. The fork point (old remote
ref) of the branch from the upstream branch is calculated before fetch,
and then rebased from onto the new remote head (merge_head) after fetch.
Re-implement this by introducing get_merge_branch_2() and
get_merge_branch_1() to find the upstream branch for the
specified/current branch, and get_rebase_fork_point() which will find
the fork point between the upstream branch and current branch.
However, the above change created a problem where git-rebase cannot
detect commits that are already upstream, and thus may result in
unnecessary conflicts. cf65426 (pull --rebase: Avoid spurious conflicts
and reapplying unnecessary patches, 2010-08-12) fixes this by ignoring
the above old remote ref if it is contained within the merge base of the
merge head and the current branch.
This is re-implemented in run_rebase() where fork_point is not used if
it is the merge base returned by get_octopus_merge_base().
Helped-by: Stefan Beller <sbeller@google.com>
Helped-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Paul Tan <pyokagan@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2015-06-18 12:54:08 +02:00
|
|
|
if (opt_diffstat)
|
|
|
|
argv_array_push(&args, opt_diffstat);
|
|
|
|
argv_array_pushv(&args, opt_strategies.argv);
|
|
|
|
argv_array_pushv(&args, opt_strategy_opts.argv);
|
|
|
|
if (opt_gpg_sign)
|
|
|
|
argv_array_push(&args, opt_gpg_sign);
|
2016-03-21 19:18:03 +01:00
|
|
|
if (opt_autostash == 0)
|
|
|
|
argv_array_push(&args, "--no-autostash");
|
|
|
|
else if (opt_autostash == 1)
|
|
|
|
argv_array_push(&args, "--autostash");
|
2016-05-20 23:00:54 +02:00
|
|
|
if (opt_verify_signatures &&
|
|
|
|
!strcmp(opt_verify_signatures, "--verify-signatures"))
|
|
|
|
warning(_("ignoring --verify-signatures for rebase"));
|
pull: teach git pull about --rebase
Since cd67e4d (Teach 'git pull' about --rebase, 2007-11-28), if the
--rebase option is set, git-rebase is run instead of git-merge.
Re-implement this by introducing run_rebase(), which is called instead
of run_merge() if opt_rebase is a true value.
Since c85c792 (pull --rebase: be cleverer with rebased upstream
branches, 2008-01-26), git-pull handles the case where the upstream
branch was rebased since it was last fetched. The fork point (old remote
ref) of the branch from the upstream branch is calculated before fetch,
and then rebased from onto the new remote head (merge_head) after fetch.
Re-implement this by introducing get_merge_branch_2() and
get_merge_branch_1() to find the upstream branch for the
specified/current branch, and get_rebase_fork_point() which will find
the fork point between the upstream branch and current branch.
However, the above change created a problem where git-rebase cannot
detect commits that are already upstream, and thus may result in
unnecessary conflicts. cf65426 (pull --rebase: Avoid spurious conflicts
and reapplying unnecessary patches, 2010-08-12) fixes this by ignoring
the above old remote ref if it is contained within the merge base of the
merge head and the current branch.
This is re-implemented in run_rebase() where fork_point is not used if
it is the merge base returned by get_octopus_merge_base().
Helped-by: Stefan Beller <sbeller@google.com>
Helped-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Paul Tan <pyokagan@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2015-06-18 12:54:08 +02:00
|
|
|
|
|
|
|
argv_array_push(&args, "--onto");
|
2017-03-26 18:01:37 +02:00
|
|
|
argv_array_push(&args, oid_to_hex(merge_head));
|
pull: teach git pull about --rebase
Since cd67e4d (Teach 'git pull' about --rebase, 2007-11-28), if the
--rebase option is set, git-rebase is run instead of git-merge.
Re-implement this by introducing run_rebase(), which is called instead
of run_merge() if opt_rebase is a true value.
Since c85c792 (pull --rebase: be cleverer with rebased upstream
branches, 2008-01-26), git-pull handles the case where the upstream
branch was rebased since it was last fetched. The fork point (old remote
ref) of the branch from the upstream branch is calculated before fetch,
and then rebased from onto the new remote head (merge_head) after fetch.
Re-implement this by introducing get_merge_branch_2() and
get_merge_branch_1() to find the upstream branch for the
specified/current branch, and get_rebase_fork_point() which will find
the fork point between the upstream branch and current branch.
However, the above change created a problem where git-rebase cannot
detect commits that are already upstream, and thus may result in
unnecessary conflicts. cf65426 (pull --rebase: Avoid spurious conflicts
and reapplying unnecessary patches, 2010-08-12) fixes this by ignoring
the above old remote ref if it is contained within the merge base of the
merge head and the current branch.
This is re-implemented in run_rebase() where fork_point is not used if
it is the merge base returned by get_octopus_merge_base().
Helped-by: Stefan Beller <sbeller@google.com>
Helped-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Paul Tan <pyokagan@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2015-06-18 12:54:08 +02:00
|
|
|
|
2017-03-26 18:01:36 +02:00
|
|
|
if (fork_point && !is_null_oid(fork_point))
|
|
|
|
argv_array_push(&args, oid_to_hex(fork_point));
|
pull: teach git pull about --rebase
Since cd67e4d (Teach 'git pull' about --rebase, 2007-11-28), if the
--rebase option is set, git-rebase is run instead of git-merge.
Re-implement this by introducing run_rebase(), which is called instead
of run_merge() if opt_rebase is a true value.
Since c85c792 (pull --rebase: be cleverer with rebased upstream
branches, 2008-01-26), git-pull handles the case where the upstream
branch was rebased since it was last fetched. The fork point (old remote
ref) of the branch from the upstream branch is calculated before fetch,
and then rebased from onto the new remote head (merge_head) after fetch.
Re-implement this by introducing get_merge_branch_2() and
get_merge_branch_1() to find the upstream branch for the
specified/current branch, and get_rebase_fork_point() which will find
the fork point between the upstream branch and current branch.
However, the above change created a problem where git-rebase cannot
detect commits that are already upstream, and thus may result in
unnecessary conflicts. cf65426 (pull --rebase: Avoid spurious conflicts
and reapplying unnecessary patches, 2010-08-12) fixes this by ignoring
the above old remote ref if it is contained within the merge base of the
merge head and the current branch.
This is re-implemented in run_rebase() where fork_point is not used if
it is the merge base returned by get_octopus_merge_base().
Helped-by: Stefan Beller <sbeller@google.com>
Helped-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Paul Tan <pyokagan@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2015-06-18 12:54:08 +02:00
|
|
|
else
|
2017-03-26 18:01:37 +02:00
|
|
|
argv_array_push(&args, oid_to_hex(merge_head));
|
pull: teach git pull about --rebase
Since cd67e4d (Teach 'git pull' about --rebase, 2007-11-28), if the
--rebase option is set, git-rebase is run instead of git-merge.
Re-implement this by introducing run_rebase(), which is called instead
of run_merge() if opt_rebase is a true value.
Since c85c792 (pull --rebase: be cleverer with rebased upstream
branches, 2008-01-26), git-pull handles the case where the upstream
branch was rebased since it was last fetched. The fork point (old remote
ref) of the branch from the upstream branch is calculated before fetch,
and then rebased from onto the new remote head (merge_head) after fetch.
Re-implement this by introducing get_merge_branch_2() and
get_merge_branch_1() to find the upstream branch for the
specified/current branch, and get_rebase_fork_point() which will find
the fork point between the upstream branch and current branch.
However, the above change created a problem where git-rebase cannot
detect commits that are already upstream, and thus may result in
unnecessary conflicts. cf65426 (pull --rebase: Avoid spurious conflicts
and reapplying unnecessary patches, 2010-08-12) fixes this by ignoring
the above old remote ref if it is contained within the merge base of the
merge head and the current branch.
This is re-implemented in run_rebase() where fork_point is not used if
it is the merge base returned by get_octopus_merge_base().
Helped-by: Stefan Beller <sbeller@google.com>
Helped-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Paul Tan <pyokagan@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2015-06-18 12:54:08 +02:00
|
|
|
|
|
|
|
ret = run_command_v_opt(args.argv, RUN_GIT_CMD);
|
|
|
|
argv_array_clear(&args);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2015-06-14 10:41:51 +02:00
|
|
|
int cmd_pull(int argc, const char **argv, const char *prefix)
|
|
|
|
{
|
2015-06-14 10:41:52 +02:00
|
|
|
const char *repo, **refspecs;
|
2017-03-31 03:40:00 +02:00
|
|
|
struct oid_array merge_heads = OID_ARRAY_INIT;
|
2017-03-26 18:01:36 +02:00
|
|
|
struct object_id orig_head, curr_head;
|
|
|
|
struct object_id rebase_fork_point;
|
2017-06-01 06:18:36 +02:00
|
|
|
int autostash;
|
2015-06-14 10:41:52 +02:00
|
|
|
|
2015-06-18 12:54:07 +02:00
|
|
|
if (!getenv("GIT_REFLOG_ACTION"))
|
|
|
|
set_reflog_message(argc, argv);
|
|
|
|
|
2015-06-14 10:41:51 +02:00
|
|
|
argc = parse_options(argc, argv, prefix, pull_options, pull_usage, 0);
|
|
|
|
|
2015-06-14 10:41:52 +02:00
|
|
|
parse_repo_refspecs(argc, argv, &repo, &refspecs);
|
|
|
|
|
2015-06-18 12:54:03 +02:00
|
|
|
if (!opt_ff)
|
|
|
|
opt_ff = xstrdup_or_null(config_get_ff());
|
|
|
|
|
2015-06-18 12:54:09 +02:00
|
|
|
if (opt_rebase < 0)
|
|
|
|
opt_rebase = config_get_rebase();
|
|
|
|
|
2016-03-21 19:18:02 +01:00
|
|
|
git_config(git_pull_config, NULL);
|
2015-06-18 12:54:04 +02:00
|
|
|
|
|
|
|
if (read_cache_unmerged())
|
2016-06-17 22:20:52 +02:00
|
|
|
die_resolve_conflict("pull");
|
2015-06-18 12:54:04 +02:00
|
|
|
|
2017-04-20 23:08:54 +02:00
|
|
|
if (file_exists(git_path_merge_head()))
|
2015-06-18 12:54:04 +02:00
|
|
|
die_conclude_merge();
|
|
|
|
|
2017-03-26 18:01:36 +02:00
|
|
|
if (get_oid("HEAD", &orig_head))
|
|
|
|
oidclr(&orig_head);
|
2015-06-18 12:54:05 +02:00
|
|
|
|
2016-03-21 19:18:03 +01:00
|
|
|
if (!opt_rebase && opt_autostash != -1)
|
|
|
|
die(_("--[no-]autostash option is only valid with --rebase."));
|
|
|
|
|
2017-06-01 06:18:36 +02:00
|
|
|
autostash = config_autostash;
|
2015-06-18 12:54:10 +02:00
|
|
|
if (opt_rebase) {
|
2016-03-21 19:18:03 +01:00
|
|
|
if (opt_autostash != -1)
|
|
|
|
autostash = opt_autostash;
|
2015-07-04 23:42:38 +02:00
|
|
|
|
2017-03-26 18:01:36 +02:00
|
|
|
if (is_null_oid(&orig_head) && !is_cache_unborn())
|
2015-06-18 12:54:10 +02:00
|
|
|
die(_("Updating an unborn branch with changes added to the index."));
|
|
|
|
|
2015-07-04 23:42:38 +02:00
|
|
|
if (!autostash)
|
2016-10-07 18:08:34 +02:00
|
|
|
require_clean_work_tree(N_("pull with rebase"),
|
2016-10-07 18:09:00 +02:00
|
|
|
_("please commit or stash them."), 1, 0);
|
2015-06-18 12:54:10 +02:00
|
|
|
|
2017-03-26 18:01:36 +02:00
|
|
|
if (get_rebase_fork_point(&rebase_fork_point, repo, *refspecs))
|
|
|
|
oidclr(&rebase_fork_point);
|
2015-06-18 12:54:10 +02:00
|
|
|
}
|
pull: teach git pull about --rebase
Since cd67e4d (Teach 'git pull' about --rebase, 2007-11-28), if the
--rebase option is set, git-rebase is run instead of git-merge.
Re-implement this by introducing run_rebase(), which is called instead
of run_merge() if opt_rebase is a true value.
Since c85c792 (pull --rebase: be cleverer with rebased upstream
branches, 2008-01-26), git-pull handles the case where the upstream
branch was rebased since it was last fetched. The fork point (old remote
ref) of the branch from the upstream branch is calculated before fetch,
and then rebased from onto the new remote head (merge_head) after fetch.
Re-implement this by introducing get_merge_branch_2() and
get_merge_branch_1() to find the upstream branch for the
specified/current branch, and get_rebase_fork_point() which will find
the fork point between the upstream branch and current branch.
However, the above change created a problem where git-rebase cannot
detect commits that are already upstream, and thus may result in
unnecessary conflicts. cf65426 (pull --rebase: Avoid spurious conflicts
and reapplying unnecessary patches, 2010-08-12) fixes this by ignoring
the above old remote ref if it is contained within the merge base of the
merge head and the current branch.
This is re-implemented in run_rebase() where fork_point is not used if
it is the merge base returned by get_octopus_merge_base().
Helped-by: Stefan Beller <sbeller@google.com>
Helped-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Paul Tan <pyokagan@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2015-06-18 12:54:08 +02:00
|
|
|
|
2015-06-14 10:41:52 +02:00
|
|
|
if (run_fetch(repo, refspecs))
|
|
|
|
return 1;
|
|
|
|
|
2015-06-18 12:54:01 +02:00
|
|
|
if (opt_dry_run)
|
|
|
|
return 0;
|
|
|
|
|
2017-03-26 18:01:36 +02:00
|
|
|
if (get_oid("HEAD", &curr_head))
|
|
|
|
oidclr(&curr_head);
|
2015-06-18 12:54:05 +02:00
|
|
|
|
2017-03-26 18:01:36 +02:00
|
|
|
if (!is_null_oid(&orig_head) && !is_null_oid(&curr_head) &&
|
|
|
|
oidcmp(&orig_head, &curr_head)) {
|
2015-06-18 12:54:05 +02:00
|
|
|
/*
|
|
|
|
* The fetch involved updating the current branch.
|
|
|
|
*
|
|
|
|
* The working tree and the index file are still based on
|
|
|
|
* orig_head commit, but we are merging into curr_head.
|
|
|
|
* Update the working tree to match curr_head.
|
|
|
|
*/
|
|
|
|
|
|
|
|
warning(_("fetch updated the current branch head.\n"
|
|
|
|
"fast-forwarding your working tree from\n"
|
2017-03-26 18:01:36 +02:00
|
|
|
"commit %s."), oid_to_hex(&orig_head));
|
2015-06-18 12:54:05 +02:00
|
|
|
|
2017-05-07 00:10:33 +02:00
|
|
|
if (checkout_fast_forward(&orig_head, &curr_head, 0))
|
2015-06-18 12:54:05 +02:00
|
|
|
die(_("Cannot fast-forward your working tree.\n"
|
|
|
|
"After making sure that you saved anything precious from\n"
|
|
|
|
"$ git diff %s\n"
|
|
|
|
"output, run\n"
|
|
|
|
"$ git reset --hard\n"
|
2017-03-26 18:01:36 +02:00
|
|
|
"to recover."), oid_to_hex(&orig_head));
|
2015-06-18 12:54:05 +02:00
|
|
|
}
|
|
|
|
|
pull: error on no merge candidates
Commit a8c9bef (pull: improve advice for unconfigured error case,
2009-10-05) fully established the current advices given by git-pull for
the different cases where git-fetch will not have anything marked for
merge:
1. We fetched from a specific remote, and a refspec was given, but it
ended up not fetching anything. This is usually because the user
provided a wildcard refspec which had no matches on the remote end.
2. We fetched from a non-default remote, but didn't specify a branch to
merge. We can't use the configured one because it applies to the
default remote, and thus the user must specify the branches to merge.
3. We fetched from the branch's or repo's default remote, but:
a. We are not on a branch, so there will never be a configured branch
to merge with.
b. We are on a branch, but there is no configured branch to merge
with.
4. We fetched from the branch's or repo's default remote, but the
configured branch to merge didn't get fetched (either it doesn't
exist, or wasn't part of the configured fetch refspec)
Re-implement the above behavior by implementing get_merge_heads() to
parse the heads in FETCH_HEAD for merging, and implementing
die_no_merge_candidates(), which will be called when FETCH_HEAD has no
heads for merging.
Helped-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Helped-by: Junio C Hamano <gitster@pobox.com>
Signed-off-by: Paul Tan <pyokagan@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2015-06-18 12:54:02 +02:00
|
|
|
get_merge_heads(&merge_heads);
|
|
|
|
|
|
|
|
if (!merge_heads.nr)
|
|
|
|
die_no_merge_candidates(repo, refspecs);
|
|
|
|
|
2017-03-26 18:01:36 +02:00
|
|
|
if (is_null_oid(&orig_head)) {
|
2015-06-18 12:54:06 +02:00
|
|
|
if (merge_heads.nr > 1)
|
|
|
|
die(_("Cannot merge multiple branches into empty head."));
|
2017-03-26 18:01:37 +02:00
|
|
|
return pull_into_void(merge_heads.oid, &curr_head);
|
2016-06-29 19:22:31 +02:00
|
|
|
}
|
|
|
|
if (opt_rebase && merge_heads.nr > 1)
|
|
|
|
die(_("Cannot rebase onto multiple branches."));
|
|
|
|
|
|
|
|
if (opt_rebase) {
|
pull: optionally rebase submodules (remote submodule changes only)
Teach pull to optionally update submodules when '--recurse-submodules'
is provided. This will teach pull to run 'submodule update --rebase'
when the '--recurse-submodules' and '--rebase' flags are given under
specific circumstances.
On a rebase workflow:
=====================
1. Both sides change the submodule
------------------------------
Let's assume the following history in a submodule:
H---I---J---K---L local branch
\
M---N---O---P remote branch
and the following in the superproject (recorded submodule in parens):
A(H)---B(I)---F(K)---G(L) local branch
\
C(N)---D(N)---E(P) remote branch
In an ideal world this would rebase the submodule and rewrite
the submodule pointers that the superproject points at such that
the superproject looks like
A(H)---B(I) F(K')---G(L') rebased branch
\ /
C(N)---D(N)---E(P) remote branch
and the submodule as:
J---K---L (old dangeling tip)
/
H---I J'---K'---L' rebased branch
\ /
M---N---O---P remote branch
And if a conflict arises in the submodule the superproject rebase
would stop at that commit at which the submodule conflict occurs.
Currently a "pull --rebase" in the superproject produces
a merge conflict as the submodule pointer changes are
conflicting and cannot be resolved.
2. Local submodule changes only
-----------------------
Assuming histories as above, except that the remote branch
would not contain submodule changes, then a result as
A(H)---B(I) F(K)---G(L) rebased branch
\ /
C(I)---D(I)---E(I) remote branch
is desire-able. This is what currently happens in rebase.
If the recursive flag is given, the ideal git would
produce a superproject as:
A(H)---B(I) F(K')---G(L') rebased branch (incl. sub rebase!)
\ /
C(I)---D(I)---E(I) remote branch
and the submodule as:
J---K---L (old dangeling tip)
/
H---I J'---K'---L' locally rebased branch
\ /
M---N---O---P advanced branch
This patch doesn't address this issue, however
a test is added that this fails up front.
3. Remote submodule changes only
----------------------
Assuming histories as in (1) except that the local superproject branch
would not have touched the submodule the rebase already works out in the
superproject with no conflicts:
A(H)---B(I) F(P)---G(P) rebased branch (no sub changes)
\ /
C(N)---D(N)---E(P) remote branch
The recurse flag as presented in this patch would additionally
update the submodule as:
H---I J'---K'---L' rebased branch
\ /
M---N---O---P remote branch
As neither J, K, L nor J', K', L' are referred to from the superproject,
no rewriting of the superproject commits is required.
Conclusion for 'pull --rebase --recursive'
-----------------------------------------
If there are no local superproject changes it is sufficient to call
"submodule update --rebase" as this produces the desired results. In case
of conflicts, the behavior is the same as in 'submodule update --recursive'
which is assumed to be sane.
This patch implements (3) only.
On a merge workflow:
====================
We'll start off with the same underlying DAG as in (1) in the rebase
workflow. So in an ideal world a 'pull --merge --recursive' would
produce this:
H---I---J---K---L----X
\ /
M---N---O---P
with X as the new merge-commit in the submodule and the superproject
as:
A(H)---B(I)---F(K)---G(L)---Y(X)
\ /
C(N)---D(N)---E(P)
However modifying the submodules on the fly is not supported in git-merge
such that Y(X) is not easy to produce in a single patch. In fact git-merge
doesn't know about submodules at all.
However when at least one side does not contain commits touching the
submodule at all, then we do not need to perform the merge for the
submodule but a fast-forward can be done via checking out either L or P
in the submodule. This strategy is implemented in 68d03e4a6e (Implement
automatic fast-forward merge for submodules, 2010-07-07) already, so
to align with the rebase behavior we need to also update the worktree
of the submodule.
Signed-off-by: Brandon Williams <bmwill@google.com>
Signed-off-by: Stefan Beller <sbeller@google.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-06-23 21:13:02 +02:00
|
|
|
int ret = 0;
|
|
|
|
if ((recurse_submodules == RECURSE_SUBMODULES_ON ||
|
|
|
|
recurse_submodules == RECURSE_SUBMODULES_ON_DEMAND) &&
|
|
|
|
submodule_touches_in_range(&rebase_fork_point, &curr_head))
|
|
|
|
die(_("cannot rebase with locally recorded submodule modifications"));
|
2017-06-01 06:18:36 +02:00
|
|
|
if (!autostash) {
|
|
|
|
struct commit_list *list = NULL;
|
|
|
|
struct commit *merge_head, *head;
|
|
|
|
|
2017-06-05 02:18:13 +02:00
|
|
|
head = lookup_commit_reference(&orig_head);
|
2017-06-01 06:18:36 +02:00
|
|
|
commit_list_insert(head, &list);
|
2017-06-05 02:18:13 +02:00
|
|
|
merge_head = lookup_commit_reference(&merge_heads.oid[0]);
|
2017-06-01 06:18:36 +02:00
|
|
|
if (is_descendant_of(merge_head, list)) {
|
|
|
|
/* we can fast-forward this without invoking rebase */
|
|
|
|
opt_ff = "--ff-only";
|
pull: optionally rebase submodules (remote submodule changes only)
Teach pull to optionally update submodules when '--recurse-submodules'
is provided. This will teach pull to run 'submodule update --rebase'
when the '--recurse-submodules' and '--rebase' flags are given under
specific circumstances.
On a rebase workflow:
=====================
1. Both sides change the submodule
------------------------------
Let's assume the following history in a submodule:
H---I---J---K---L local branch
\
M---N---O---P remote branch
and the following in the superproject (recorded submodule in parens):
A(H)---B(I)---F(K)---G(L) local branch
\
C(N)---D(N)---E(P) remote branch
In an ideal world this would rebase the submodule and rewrite
the submodule pointers that the superproject points at such that
the superproject looks like
A(H)---B(I) F(K')---G(L') rebased branch
\ /
C(N)---D(N)---E(P) remote branch
and the submodule as:
J---K---L (old dangeling tip)
/
H---I J'---K'---L' rebased branch
\ /
M---N---O---P remote branch
And if a conflict arises in the submodule the superproject rebase
would stop at that commit at which the submodule conflict occurs.
Currently a "pull --rebase" in the superproject produces
a merge conflict as the submodule pointer changes are
conflicting and cannot be resolved.
2. Local submodule changes only
-----------------------
Assuming histories as above, except that the remote branch
would not contain submodule changes, then a result as
A(H)---B(I) F(K)---G(L) rebased branch
\ /
C(I)---D(I)---E(I) remote branch
is desire-able. This is what currently happens in rebase.
If the recursive flag is given, the ideal git would
produce a superproject as:
A(H)---B(I) F(K')---G(L') rebased branch (incl. sub rebase!)
\ /
C(I)---D(I)---E(I) remote branch
and the submodule as:
J---K---L (old dangeling tip)
/
H---I J'---K'---L' locally rebased branch
\ /
M---N---O---P advanced branch
This patch doesn't address this issue, however
a test is added that this fails up front.
3. Remote submodule changes only
----------------------
Assuming histories as in (1) except that the local superproject branch
would not have touched the submodule the rebase already works out in the
superproject with no conflicts:
A(H)---B(I) F(P)---G(P) rebased branch (no sub changes)
\ /
C(N)---D(N)---E(P) remote branch
The recurse flag as presented in this patch would additionally
update the submodule as:
H---I J'---K'---L' rebased branch
\ /
M---N---O---P remote branch
As neither J, K, L nor J', K', L' are referred to from the superproject,
no rewriting of the superproject commits is required.
Conclusion for 'pull --rebase --recursive'
-----------------------------------------
If there are no local superproject changes it is sufficient to call
"submodule update --rebase" as this produces the desired results. In case
of conflicts, the behavior is the same as in 'submodule update --recursive'
which is assumed to be sane.
This patch implements (3) only.
On a merge workflow:
====================
We'll start off with the same underlying DAG as in (1) in the rebase
workflow. So in an ideal world a 'pull --merge --recursive' would
produce this:
H---I---J---K---L----X
\ /
M---N---O---P
with X as the new merge-commit in the submodule and the superproject
as:
A(H)---B(I)---F(K)---G(L)---Y(X)
\ /
C(N)---D(N)---E(P)
However modifying the submodules on the fly is not supported in git-merge
such that Y(X) is not easy to produce in a single patch. In fact git-merge
doesn't know about submodules at all.
However when at least one side does not contain commits touching the
submodule at all, then we do not need to perform the merge for the
submodule but a fast-forward can be done via checking out either L or P
in the submodule. This strategy is implemented in 68d03e4a6e (Implement
automatic fast-forward merge for submodules, 2010-07-07) already, so
to align with the rebase behavior we need to also update the worktree
of the submodule.
Signed-off-by: Brandon Williams <bmwill@google.com>
Signed-off-by: Stefan Beller <sbeller@google.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-06-23 21:13:02 +02:00
|
|
|
ret = run_merge();
|
2017-06-01 06:18:36 +02:00
|
|
|
}
|
2016-06-29 19:22:31 +02:00
|
|
|
}
|
pull: optionally rebase submodules (remote submodule changes only)
Teach pull to optionally update submodules when '--recurse-submodules'
is provided. This will teach pull to run 'submodule update --rebase'
when the '--recurse-submodules' and '--rebase' flags are given under
specific circumstances.
On a rebase workflow:
=====================
1. Both sides change the submodule
------------------------------
Let's assume the following history in a submodule:
H---I---J---K---L local branch
\
M---N---O---P remote branch
and the following in the superproject (recorded submodule in parens):
A(H)---B(I)---F(K)---G(L) local branch
\
C(N)---D(N)---E(P) remote branch
In an ideal world this would rebase the submodule and rewrite
the submodule pointers that the superproject points at such that
the superproject looks like
A(H)---B(I) F(K')---G(L') rebased branch
\ /
C(N)---D(N)---E(P) remote branch
and the submodule as:
J---K---L (old dangeling tip)
/
H---I J'---K'---L' rebased branch
\ /
M---N---O---P remote branch
And if a conflict arises in the submodule the superproject rebase
would stop at that commit at which the submodule conflict occurs.
Currently a "pull --rebase" in the superproject produces
a merge conflict as the submodule pointer changes are
conflicting and cannot be resolved.
2. Local submodule changes only
-----------------------
Assuming histories as above, except that the remote branch
would not contain submodule changes, then a result as
A(H)---B(I) F(K)---G(L) rebased branch
\ /
C(I)---D(I)---E(I) remote branch
is desire-able. This is what currently happens in rebase.
If the recursive flag is given, the ideal git would
produce a superproject as:
A(H)---B(I) F(K')---G(L') rebased branch (incl. sub rebase!)
\ /
C(I)---D(I)---E(I) remote branch
and the submodule as:
J---K---L (old dangeling tip)
/
H---I J'---K'---L' locally rebased branch
\ /
M---N---O---P advanced branch
This patch doesn't address this issue, however
a test is added that this fails up front.
3. Remote submodule changes only
----------------------
Assuming histories as in (1) except that the local superproject branch
would not have touched the submodule the rebase already works out in the
superproject with no conflicts:
A(H)---B(I) F(P)---G(P) rebased branch (no sub changes)
\ /
C(N)---D(N)---E(P) remote branch
The recurse flag as presented in this patch would additionally
update the submodule as:
H---I J'---K'---L' rebased branch
\ /
M---N---O---P remote branch
As neither J, K, L nor J', K', L' are referred to from the superproject,
no rewriting of the superproject commits is required.
Conclusion for 'pull --rebase --recursive'
-----------------------------------------
If there are no local superproject changes it is sufficient to call
"submodule update --rebase" as this produces the desired results. In case
of conflicts, the behavior is the same as in 'submodule update --recursive'
which is assumed to be sane.
This patch implements (3) only.
On a merge workflow:
====================
We'll start off with the same underlying DAG as in (1) in the rebase
workflow. So in an ideal world a 'pull --merge --recursive' would
produce this:
H---I---J---K---L----X
\ /
M---N---O---P
with X as the new merge-commit in the submodule and the superproject
as:
A(H)---B(I)---F(K)---G(L)---Y(X)
\ /
C(N)---D(N)---E(P)
However modifying the submodules on the fly is not supported in git-merge
such that Y(X) is not easy to produce in a single patch. In fact git-merge
doesn't know about submodules at all.
However when at least one side does not contain commits touching the
submodule at all, then we do not need to perform the merge for the
submodule but a fast-forward can be done via checking out either L or P
in the submodule. This strategy is implemented in 68d03e4a6e (Implement
automatic fast-forward merge for submodules, 2010-07-07) already, so
to align with the rebase behavior we need to also update the worktree
of the submodule.
Signed-off-by: Brandon Williams <bmwill@google.com>
Signed-off-by: Stefan Beller <sbeller@google.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-06-23 21:13:02 +02:00
|
|
|
ret = run_rebase(&curr_head, merge_heads.oid, &rebase_fork_point);
|
|
|
|
|
|
|
|
if (!ret && (recurse_submodules == RECURSE_SUBMODULES_ON ||
|
|
|
|
recurse_submodules == RECURSE_SUBMODULES_ON_DEMAND))
|
|
|
|
ret = rebase_submodules();
|
|
|
|
|
|
|
|
return ret;
|
2016-06-29 19:22:31 +02:00
|
|
|
} else {
|
pull: optionally rebase submodules (remote submodule changes only)
Teach pull to optionally update submodules when '--recurse-submodules'
is provided. This will teach pull to run 'submodule update --rebase'
when the '--recurse-submodules' and '--rebase' flags are given under
specific circumstances.
On a rebase workflow:
=====================
1. Both sides change the submodule
------------------------------
Let's assume the following history in a submodule:
H---I---J---K---L local branch
\
M---N---O---P remote branch
and the following in the superproject (recorded submodule in parens):
A(H)---B(I)---F(K)---G(L) local branch
\
C(N)---D(N)---E(P) remote branch
In an ideal world this would rebase the submodule and rewrite
the submodule pointers that the superproject points at such that
the superproject looks like
A(H)---B(I) F(K')---G(L') rebased branch
\ /
C(N)---D(N)---E(P) remote branch
and the submodule as:
J---K---L (old dangeling tip)
/
H---I J'---K'---L' rebased branch
\ /
M---N---O---P remote branch
And if a conflict arises in the submodule the superproject rebase
would stop at that commit at which the submodule conflict occurs.
Currently a "pull --rebase" in the superproject produces
a merge conflict as the submodule pointer changes are
conflicting and cannot be resolved.
2. Local submodule changes only
-----------------------
Assuming histories as above, except that the remote branch
would not contain submodule changes, then a result as
A(H)---B(I) F(K)---G(L) rebased branch
\ /
C(I)---D(I)---E(I) remote branch
is desire-able. This is what currently happens in rebase.
If the recursive flag is given, the ideal git would
produce a superproject as:
A(H)---B(I) F(K')---G(L') rebased branch (incl. sub rebase!)
\ /
C(I)---D(I)---E(I) remote branch
and the submodule as:
J---K---L (old dangeling tip)
/
H---I J'---K'---L' locally rebased branch
\ /
M---N---O---P advanced branch
This patch doesn't address this issue, however
a test is added that this fails up front.
3. Remote submodule changes only
----------------------
Assuming histories as in (1) except that the local superproject branch
would not have touched the submodule the rebase already works out in the
superproject with no conflicts:
A(H)---B(I) F(P)---G(P) rebased branch (no sub changes)
\ /
C(N)---D(N)---E(P) remote branch
The recurse flag as presented in this patch would additionally
update the submodule as:
H---I J'---K'---L' rebased branch
\ /
M---N---O---P remote branch
As neither J, K, L nor J', K', L' are referred to from the superproject,
no rewriting of the superproject commits is required.
Conclusion for 'pull --rebase --recursive'
-----------------------------------------
If there are no local superproject changes it is sufficient to call
"submodule update --rebase" as this produces the desired results. In case
of conflicts, the behavior is the same as in 'submodule update --recursive'
which is assumed to be sane.
This patch implements (3) only.
On a merge workflow:
====================
We'll start off with the same underlying DAG as in (1) in the rebase
workflow. So in an ideal world a 'pull --merge --recursive' would
produce this:
H---I---J---K---L----X
\ /
M---N---O---P
with X as the new merge-commit in the submodule and the superproject
as:
A(H)---B(I)---F(K)---G(L)---Y(X)
\ /
C(N)---D(N)---E(P)
However modifying the submodules on the fly is not supported in git-merge
such that Y(X) is not easy to produce in a single patch. In fact git-merge
doesn't know about submodules at all.
However when at least one side does not contain commits touching the
submodule at all, then we do not need to perform the merge for the
submodule but a fast-forward can be done via checking out either L or P
in the submodule. This strategy is implemented in 68d03e4a6e (Implement
automatic fast-forward merge for submodules, 2010-07-07) already, so
to align with the rebase behavior we need to also update the worktree
of the submodule.
Signed-off-by: Brandon Williams <bmwill@google.com>
Signed-off-by: Stefan Beller <sbeller@google.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-06-23 21:13:02 +02:00
|
|
|
int ret = run_merge();
|
|
|
|
if (!ret && (recurse_submodules == RECURSE_SUBMODULES_ON ||
|
|
|
|
recurse_submodules == RECURSE_SUBMODULES_ON_DEMAND))
|
|
|
|
ret = update_submodules();
|
|
|
|
return ret;
|
2016-06-29 19:22:31 +02:00
|
|
|
}
|
2015-06-14 10:41:51 +02:00
|
|
|
}
|