[2/6] documents existing push.default modes properly, but doesn't
touch `simple`. It incorporates feedback from Junio, Philip Oakley,
Matthieu Moy.
[3/6] gives `simple` an exciting new meaning. I think it's an
absolutely fabulous default! It's aimed at triangular people who
occassionally need to do central stuff.
[6/6] adds some new tests to illustrate how all these push.default
modes work in central and triangular workflows.
Thanks.
Ramkumar Ramachandra (6):
t/t5528-push-default: remove redundant test_config lines
config doc: rewrite push.default section
push: change `simple` to accommodate triangular workflows
push: remove dead code in setup_push_upstream()
t/t5528-push-default: generalize test_push_*
t/t5528-push-default: test pushdefault workflows
Documentation/config.txt | 62 ++++++++++++++++++++++++++----------------------
builtin/push.c | 27 +++++++++++++++++----
t/t5528-push-default.sh | 46 +++++++++++++++++++++++++++++++----
3 files changed, 97 insertions(+), 38 deletions(-)
--
1.8.3.1.454.g30263f3.dirty
The line
test_config push.default upstream
appears unnecessarily in two tests, as the final test_push_failure sets
push.default before pushing anyway.
Signed-off-by: Ramkumar Ramachandra <redacted>
---
t/t5528-push-default.sh | 2 --
1 file changed, 2 deletions(-)
@@ -48,7 +48,6 @@ test_expect_success '"upstream" pushes to configured upstream' ' test_expect_success'"upstream" does not push on unconfigured remote''gitcheckoutmaster&&test_unconfigbranch.master.remote&&-test_configpush.defaultupstream&&test_committhree&&test_push_failureupstream'
@@ -57,7 +56,6 @@ test_expect_success '"upstream" does not push on unconfigured branch' 'gitcheckoutmaster&&test_configbranch.master.remoteparent1&&test_unconfigbranch.master.merge&&-test_configpush.defaultupstreamtest_commitfour&&test_push_failureupstream'
4d3592 (Merge branch 'rr/triangle', 2013-04-07) introduced support for
triangular workflows in Git, but the push.default values still assume
central workflows. Rewrite the descriptions of `nothing`, `current`,
`upstream` and `matching` for greater clarity, and explicitly explaining
how they behave in triangular workflows. Leave `simple` as it is for
the moment, as we plan to change its meaning to accommodate triangular
workflows in a later patch.
Signed-off-by: Ramkumar Ramachandra <redacted>
---
Documentation/config.txt | 56 ++++++++++++++++++++++++++----------------------
1 file changed, 30 insertions(+), 26 deletions(-)
@@ -1826,39 +1826,43 @@ pull.twohead:: The default merge strategy to use when pulling a single branch. push.default::- Defines the action `git push` should take if no refspec is given- on the command line, no refspec is configured in the remote, and- no refspec is implied by any of the options given on the command- line. Possible values are:+ Defines the action `git push` should take if no refspec is+ explicitly given. Different values are well-suited for+ specific workflows; for instance, in a purely central workflow+ (i.e. the fetch source is equal to the push destination),+ `upstream` is probably what you want. Possible values are: + ---* `nothing` - do not push anything.-* `matching` - push all branches having the same name in both ends.- This is for those who prepare all the branches into a publishable- shape and then push them out with a single command. It is not- appropriate for pushing into a repository shared by multiple users,- since locally stalled branches will attempt a non-fast forward push- if other users updated the branch.- +- This is currently the default, but Git 2.0 will change the default- to `simple`.-* `upstream` - push the current branch to its upstream branch- (`tracking` is a deprecated synonym for this).- With this, `git push` will update the same remote ref as the one which- is merged by `git pull`, making `push` and `pull` symmetrical.- See "branch.<name>.merge" for how to configure the upstream branch.+* `nothing` - do not push anything (error out) unless a refspec is+ explicitly given. Very safe, but not very convenient.++* `current` - push the current branch to update a branch with the same+ name on the receiving end. Works in both central and non-central+ workflows. Equivalent to pushing the refspec "$branch" ($branch is+ the name of the current branch).++* `upstream` - push the current branch to a branch with the name+ branch.$branch.merge on the receiving end, and error out if the push+ destination is not the same as branch.$branch.remote. The name+ "upstream" refers to "@{u[pstream]}" in linkgit:gitrevisions[7],+ which makes sense only if both branch.$branch.remote and+ branch.$branch.merge are set. It makes sure that a `push` is+ symmetrical to `pull` in central workflows, and cannot be used in+ non-central workflows.+ * `simple` - like `upstream`, but refuses to push if the upstream branch's name is different from the local one. This is the safest option and is well-suited for beginners. It will become the default in Git 2.0.-* `current` - push the current branch to a branch of the same name.++* `matching` - push all branches having the same name on both ends+ (essentially ignoring all newly created local branches).+ Well-suited for those who want to batch-update a specific set of+ branches they consistently work on. Use with caution, especially+ when pushing with '--force'. Equivalent to pushing the refspec ":".+ This is currently the default, but Git 2.0 will change the default+ to `simple`. ---+-The `simple`, `current` and `upstream` modes are for those who want to-push out a single branch after finishing work, even when the other-branches are not yet ready to be pushed out. If you are working with-other people to push into the same shared repository, you would want-to use one of these. rebase.stat:: Whether to show a diffstat of what changed upstream since the last
When remote.pushdefault or branch.<name>.pushremote is set (a triangular
workflow feature), master@{u} != origin, and push.default is set to
`upstream` or `simple`:
$ git push
fatal: You are pushing to remote 'origin', which is not the upstream of
your current branch 'master', without telling me what to push
to update which remote branch.
Unfortunately, in the case of `upstream`, the very name indicates that
it is only suitable for use in central workflows; let us not even
attempt to give it a new meaning in triangular workflows, and error out
as usual. However, the `simple` does not have this problem: it is
poised to be the default for Git 2.0, and we would definitely like it to
do something sensible in triangular workflows.
Decouple `simple` from `upstream` completely, and change it to mean
`current` with a safety feature: a `push` and `pull` should not be
asymmetrical in the special case of central workflows.
Reported-by: Leandro Lucarella <redacted>
Signed-off-by: Ramkumar Ramachandra <redacted>
---
Documentation/config.txt | 10 ++++++----
builtin/push.c | 21 ++++++++++++++++++++-
t/t5528-push-default.sh | 2 +-
3 files changed, 27 insertions(+), 6 deletions(-)
@@ -1850,10 +1850,12 @@ push.default:: symmetrical to `pull` in central workflows, and cannot be used in non-central workflows.-* `simple` - like `upstream`, but refuses to push if the upstream- branch's name is different from the local one. This is the safest- option and is well-suited for beginners. It will become the default- in Git 2.0.+* `simple` - a safer version of `current`; push the current branch to+ update a branch with the same name on the receiving end, with a+ safety feature: in central workflows, error out if+ branch.$branch.merge is set and not equal to $branch, to make sure+ that a `push` and `push` are never asymmetrical. It will become the+ default in Git 2.0. * `matching` - push all branches having the same name on both ends (essentially ignoring all newly created local branches).
@@ -85,7 +85,7 @@ test_expect_success 'push from/to new branch with current creates remote branch' test_expect_success'push to existing branch, with no upstream configured''test_configbranch.master.remoterepo1&&gitcheckoutmaster&&-test_push_failuresimple&&+test_push_successsimplemaster&&test_push_failureupstream'
Now that simple has been decoupled from upstream in setup_push_simple(),
remove the dead code in setup_push_upstream().
Signed-off-by: Ramkumar Ramachandra <redacted>
---
builtin/push.c | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
@@ -161,8 +161,6 @@ static void setup_push_upstream(struct remote *remote, int simple)"your current branch '%s', without telling me what to push\n""to update which remote branch."),remote->name,branch->name);-if(simple&&strcmp(branch->refname,branch->merge[0]->src))-die_push_simple(branch,remote);strbuf_addf(&refspec,"%s:%s",branch->name,branch->merge[0]->src);add_refspec(refspec.buf);
The setup creates two bare repositories: repo1 and repo2, but
test_push_commit() hard-codes checking in repo1 for the actual output.
Generalize it and its caller, test_push_success(), to optionally accept
a third argument to specify the name of the repository to check for
actual output. We will use this in the next patch.
Signed-off-by: Ramkumar Ramachandra <redacted>
---
t/t5528-push-default.sh | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
@@ -15,17 +15,19 @@ test_expect_success 'setup bare remotes' '# $1 = local revision# $2 = remote revision (tested to be equal to the local one)+# $3 = [optional] repo to check for actual output (repo1 by default) check_pushed_commit(){gitlog-1--format='%h %s'"$1">expect&&-git--git-dir=repo1log-1--format='%h %s'"$2">actual&&+git--git-dir="${3:-repo1}"log-1--format='%h %s'"$2">actual&&test_cmpexpectactual}# $1 = push.default value# $2 = expected target branch for the push+# $3 = [optional] repo to check for actual output (repo1 by default) test_push_success(){git-cpush.default="$1"push&&-check_pushed_commitHEAD"$2"+check_pushed_commitHEAD"$2""$3"}# $1 = push.default value
Introduce test_pushdefault_workflows(), and test that all push.default
modes work with central and triangular workflows as expected.
Signed-off-by: Ramkumar Ramachandra <redacted>
---
t/t5528-push-default.sh | 36 ++++++++++++++++++++++++++++++++++++
1 file changed, 36 insertions(+)