Merge branch 'maint'
* maint: push: point to 'git pull' and 'git push --force' in case of non-fast forward Documentation: add: <filepattern>... is optional Change mentions of "git programs" to "git commands" Documentation: merge: one <remote> is required help.c: give correct structure's size to memset()
This commit is contained in:
commit
6ffd781226
@ -605,7 +605,7 @@ color.interactive.<slot>::
|
||||
Use customized color for 'git-add --interactive'
|
||||
output. `<slot>` may be `prompt`, `header`, `help` or `error`, for
|
||||
four distinct types of normal output from interactive
|
||||
programs. The values of these variables may be specified as
|
||||
commands. The values of these variables may be specified as
|
||||
in color.branch.<slot>.
|
||||
|
||||
color.pager::
|
||||
@ -1113,7 +1113,7 @@ instaweb.port::
|
||||
linkgit:git-instaweb[1].
|
||||
|
||||
interactive.singlekey::
|
||||
In interactive programs, allow the user to provide one-letter
|
||||
In interactive commands, allow the user to provide one-letter
|
||||
input with a single key (i.e., without hitting enter).
|
||||
Currently this is used only by the `\--patch` mode of
|
||||
linkgit:git-add[1]. Note that this setting is silently
|
||||
|
@ -1,7 +1,7 @@
|
||||
-q::
|
||||
--quiet::
|
||||
Pass --quiet to git-fetch-pack and silence any other internally
|
||||
used programs.
|
||||
used git commands.
|
||||
|
||||
-v::
|
||||
--verbose::
|
||||
|
@ -10,7 +10,7 @@ SYNOPSIS
|
||||
[verse]
|
||||
'git add' [-n] [-v] [--force | -f] [--interactive | -i] [--patch | -p]
|
||||
[--edit | -e] [--all | [--update | -u]] [--intent-to-add | -N]
|
||||
[--refresh] [--ignore-errors] [--] <filepattern>...
|
||||
[--refresh] [--ignore-errors] [--] [<filepattern>...]
|
||||
|
||||
DESCRIPTION
|
||||
-----------
|
||||
|
@ -10,7 +10,7 @@ SYNOPSIS
|
||||
--------
|
||||
[verse]
|
||||
'git merge' [-n] [--stat] [--no-commit] [--squash] [-s <strategy>]...
|
||||
[-m <msg>] <remote> <remote>...
|
||||
[-m <msg>] <remote>...
|
||||
'git merge' <msg> HEAD <remote>...
|
||||
|
||||
DESCRIPTION
|
||||
|
@ -195,6 +195,92 @@ reason::
|
||||
refs, no explanation is needed. For a failed ref, the reason for
|
||||
failure is described.
|
||||
|
||||
Note about fast-forwards
|
||||
------------------------
|
||||
|
||||
When an update changes a branch (or more in general, a ref) that used to
|
||||
point at commit A to point at another commit B, it is called a
|
||||
fast-forward update if and only if B is a descendant of A.
|
||||
|
||||
In a fast-forward update from A to B, the set of commits that the original
|
||||
commit A built on top of is a subset of the commits the new commit B
|
||||
builds on top of. Hence, it does not lose any history.
|
||||
|
||||
In contrast, a non-fast-forward update will lose history. For example,
|
||||
suppose you and somebody else started at the same commit X, and you built
|
||||
a history leading to commit B while the other person built a history
|
||||
leading to commit A. The history looks like this:
|
||||
|
||||
----------------
|
||||
|
||||
B
|
||||
/
|
||||
---X---A
|
||||
|
||||
----------------
|
||||
|
||||
Further suppose that the other person already pushed changes leading to A
|
||||
back to the original repository you two obtained the original commit X.
|
||||
|
||||
The push done by the other person updated the branch that used to point at
|
||||
commit X to point at commit A. It is a fast-forward.
|
||||
|
||||
But if you try to push, you will attempt to update the branch (that
|
||||
now points at A) with commit B. This does _not_ fast-forward. If you did
|
||||
so, the changes introduced by commit A will be lost, because everybody
|
||||
will now start building on top of B.
|
||||
|
||||
The command by default does not allow an update that is not a fast-forward
|
||||
to prevent such loss of history.
|
||||
|
||||
If you do not want to lose your work (history from X to B) nor the work by
|
||||
the other person (history from X to A), you would need to first fetch the
|
||||
history from the repository, create a history that contains changes done
|
||||
by both parties, and push the result back.
|
||||
|
||||
You can perform "git pull", resolve potential conflicts, and "git push"
|
||||
the result. A "git pull" will create a merge commit C between commits A
|
||||
and B.
|
||||
|
||||
----------------
|
||||
|
||||
B---C
|
||||
/ /
|
||||
---X---A
|
||||
|
||||
----------------
|
||||
|
||||
Updating A with the resulting merge commit will fast-forward and your
|
||||
push will be accepted.
|
||||
|
||||
Alternatively, you can rebase your change between X and B on top of A,
|
||||
with "git pull --rebase", and push the result back. The rebase will
|
||||
create a new commit D that builds the change between X and B on top of
|
||||
A.
|
||||
|
||||
----------------
|
||||
|
||||
B D
|
||||
/ /
|
||||
---X---A
|
||||
|
||||
----------------
|
||||
|
||||
Again, updating A with this commit will fast-forward and your push will be
|
||||
accepted.
|
||||
|
||||
There is another common situation where you may encounter non-fast-forward
|
||||
rejection when you try to push, and it is possible even when you are
|
||||
pushing into a repository nobody else pushes into. After you push commit
|
||||
A yourself (in the first picture in this section), replace it with "git
|
||||
commit --amend" to produce commit B, and you try to push it out, because
|
||||
forgot that you have pushed A out already. In such a case, and only if
|
||||
you are certain that nobody in the meantime fetched your earlier commit A
|
||||
(and started building on top of it), you can run "git push --force" to
|
||||
overwrite it. In other words, "git push --force" is a method reserved for
|
||||
a case where you do mean to lose history.
|
||||
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
||||
|
@ -90,7 +90,7 @@ between the two operands. The following two commands are equivalent:
|
||||
$ git rev-list A...B
|
||||
-----------------------------------------------------------------------
|
||||
|
||||
'git-rev-list' is a very essential git program, since it
|
||||
'rev-list' is a very essential git command, since it
|
||||
provides the ability to build and traverse commit ancestry graphs. For
|
||||
this reason, it has a lot of different options that enables it to be
|
||||
used by commands as different as 'git-bisect' and
|
||||
|
@ -327,7 +327,7 @@ Synching repositories
|
||||
|
||||
include::cmds-synchingrepositories.txt[]
|
||||
|
||||
The following are helper programs used by the above; end users
|
||||
The following are helper commands used by the above; end users
|
||||
typically do not use them directly.
|
||||
|
||||
include::cmds-synchelpers.txt[]
|
||||
|
@ -404,7 +404,7 @@ Performing a three-way merge
|
||||
|
||||
The attribute `merge` affects how three versions of a file is
|
||||
merged when a file-level merge is necessary during `git merge`,
|
||||
and other programs such as `git revert` and `git cherry-pick`.
|
||||
and other commands such as `git revert` and `git cherry-pick`.
|
||||
|
||||
Set::
|
||||
|
||||
|
@ -12,7 +12,7 @@ git *
|
||||
DESCRIPTION
|
||||
-----------
|
||||
|
||||
This tutorial explains how to use the "core" git programs to set up and
|
||||
This tutorial explains how to use the "core" git commands to set up and
|
||||
work with a git repository.
|
||||
|
||||
If you just need to use git as a revision control system you may prefer
|
||||
@ -1328,7 +1328,7 @@ into it later. Obviously, this repository creation needs to be
|
||||
done only once.
|
||||
|
||||
[NOTE]
|
||||
'git-push' uses a pair of programs,
|
||||
'git-push' uses a pair of commands,
|
||||
'git-send-pack' on your local machine, and 'git-receive-pack'
|
||||
on the remote machine. The communication between the two over
|
||||
the network internally uses an SSH connection.
|
||||
|
@ -4131,7 +4131,7 @@ What does this mean?
|
||||
|
||||
`git rev-list` is the original version of the revision walker, which
|
||||
_always_ printed a list of revisions to stdout. It is still functional,
|
||||
and needs to, since most new Git programs start out as scripts using
|
||||
and needs to, since most new Git commands start out as scripts using
|
||||
`git rev-list`.
|
||||
|
||||
`git rev-parse` is not as important any more; it was only used to filter out
|
||||
|
@ -140,6 +140,7 @@ static int do_push(const char *repo, int flags)
|
||||
struct transport *transport =
|
||||
transport_get(remote, url[i]);
|
||||
int err;
|
||||
int nonfastforward;
|
||||
if (receivepack)
|
||||
transport_set_option(transport,
|
||||
TRANS_OPT_RECEIVEPACK, receivepack);
|
||||
@ -148,13 +149,19 @@ static int do_push(const char *repo, int flags)
|
||||
|
||||
if (flags & TRANSPORT_PUSH_VERBOSE)
|
||||
fprintf(stderr, "Pushing to %s\n", url[i]);
|
||||
err = transport_push(transport, refspec_nr, refspec, flags);
|
||||
err = transport_push(transport, refspec_nr, refspec, flags,
|
||||
&nonfastforward);
|
||||
err |= transport_disconnect(transport);
|
||||
|
||||
if (!err)
|
||||
continue;
|
||||
|
||||
error("failed to push some refs to '%s'", url[i]);
|
||||
if (nonfastforward) {
|
||||
printf("To prevent you from losing history, non-fast-forward updates were rejected.\n"
|
||||
"Merge the remote changes before pushing again.\n"
|
||||
"See 'non-fast forward' section of 'git push --help' for details.\n");
|
||||
}
|
||||
errs++;
|
||||
}
|
||||
return !!errs;
|
||||
|
4
help.c
4
help.c
@ -302,7 +302,7 @@ const char *help_unknown_cmd(const char *cmd)
|
||||
struct cmdnames main_cmds, other_cmds;
|
||||
|
||||
memset(&main_cmds, 0, sizeof(main_cmds));
|
||||
memset(&other_cmds, 0, sizeof(main_cmds));
|
||||
memset(&other_cmds, 0, sizeof(other_cmds));
|
||||
memset(&aliases, 0, sizeof(aliases));
|
||||
|
||||
git_config(git_unknown_cmd_config, NULL);
|
||||
@ -334,7 +334,7 @@ const char *help_unknown_cmd(const char *cmd)
|
||||
const char *assumed = main_cmds.names[0]->name;
|
||||
main_cmds.names[0] = NULL;
|
||||
clean_cmdnames(&main_cmds);
|
||||
fprintf(stderr, "WARNING: You called a Git program named '%s', "
|
||||
fprintf(stderr, "WARNING: You called a Git command named '%s', "
|
||||
"which does not exist.\n"
|
||||
"Continuing under the assumption that you meant '%s'\n",
|
||||
cmd, assumed);
|
||||
|
11
transport.c
11
transport.c
@ -821,7 +821,7 @@ static int print_one_push_status(struct ref *ref, const char *dest, int count, i
|
||||
}
|
||||
|
||||
static void print_push_status(const char *dest, struct ref *refs,
|
||||
int verbose, int porcelain)
|
||||
int verbose, int porcelain, int * nonfastforward)
|
||||
{
|
||||
struct ref *ref;
|
||||
int n = 0;
|
||||
@ -836,11 +836,14 @@ static void print_push_status(const char *dest, struct ref *refs,
|
||||
if (ref->status == REF_STATUS_OK)
|
||||
n += print_one_push_status(ref, dest, n, porcelain);
|
||||
|
||||
*nonfastforward = 0;
|
||||
for (ref = refs; ref; ref = ref->next) {
|
||||
if (ref->status != REF_STATUS_NONE &&
|
||||
ref->status != REF_STATUS_UPTODATE &&
|
||||
ref->status != REF_STATUS_OK)
|
||||
n += print_one_push_status(ref, dest, n, porcelain);
|
||||
if (ref->status == REF_STATUS_REJECT_NONFASTFORWARD)
|
||||
*nonfastforward = 1;
|
||||
}
|
||||
}
|
||||
|
||||
@ -999,7 +1002,8 @@ int transport_set_option(struct transport *transport,
|
||||
}
|
||||
|
||||
int transport_push(struct transport *transport,
|
||||
int refspec_nr, const char **refspec, int flags)
|
||||
int refspec_nr, const char **refspec, int flags,
|
||||
int * nonfastforward)
|
||||
{
|
||||
verify_remote_names(refspec_nr, refspec);
|
||||
|
||||
@ -1029,7 +1033,8 @@ int transport_push(struct transport *transport,
|
||||
|
||||
if (!quiet || push_had_errors(remote_refs))
|
||||
print_push_status(transport->url, remote_refs,
|
||||
verbose | porcelain, porcelain);
|
||||
verbose | porcelain, porcelain,
|
||||
nonfastforward);
|
||||
|
||||
if (!(flags & TRANSPORT_PUSH_DRY_RUN)) {
|
||||
struct ref *ref;
|
||||
|
@ -69,7 +69,8 @@ int transport_set_option(struct transport *transport, const char *name,
|
||||
const char *value);
|
||||
|
||||
int transport_push(struct transport *connection,
|
||||
int refspec_nr, const char **refspec, int flags);
|
||||
int refspec_nr, const char **refspec, int flags,
|
||||
int * nonfastforward);
|
||||
|
||||
const struct ref *transport_get_remote_refs(struct transport *transport);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user