Merge branch 'dl/branch-from-3dot-merge-base'
authorJunio C Hamano <gitster@pobox.com>
Sun, 19 May 2019 07:45:28 +0000 (16:45 +0900)
committerJunio C Hamano <gitster@pobox.com>
Sun, 19 May 2019 07:45:28 +0000 (16:45 +0900)
"git branch new A...B" and "git checkout -b new A...B" have been
taught that in their contexts, the notation A...B means "the merge
base between these two commits", just like "git checkout A...B"
detaches HEAD at that commit.

* dl/branch-from-3dot-merge-base:
branch: make create_branch accept a merge base rev
t2018: cleanup in current test

1  2 
Documentation/git-branch.txt
Documentation/git-checkout.txt
branch.c
t/t3200-branch.sh
index 0cd87ddeff205ac6b5a92260f690e642f16d0875,8719e4cab9bee72ccf49169250d1969b69f3db55..6ebd512b4f3344c2f166f5bb09f0b5c6eb96ab03
@@@ -9,7 -9,7 +9,7 @@@ SYNOPSI
  --------
  [verse]
  'git branch' [--color[=<when>] | --no-color] [-r | -a]
 -      [--list] [-v [--abbrev=<length> | --no-abbrev]]
 +      [--list] [--show-current] [-v [--abbrev=<length> | --no-abbrev]]
        [--column[=<options>] | --no-column] [--sort=<key>]
        [(--merged | --no-merged) [<commit>]]
        [--contains [<commit]] [--no-contains [<commit>]]
@@@ -45,7 -45,11 +45,11 @@@ argument is missing it defaults to `HEA
  branch).
  
  The command's second form creates a new branch head named <branchname>
- which points to the current `HEAD`, or <start-point> if given.
+ which points to the current `HEAD`, or <start-point> if given. As a
+ special case, for <start-point>, you may use `"A...B"` as a shortcut for
+ the merge base of `A` and `B` if there is exactly one merge base. You
+ can leave out at most one of `A` and `B`, in which case it defaults to
+ `HEAD`.
  
  Note that this will create the new branch, but it will not switch the
  working tree to it; use "git checkout <newbranch>" to switch to the
@@@ -160,10 -164,6 +164,10 @@@ This option is only applicable in non-v
        branch --list 'maint-*'`, list only the branches that match
        the pattern(s).
  
 +--show-current::
 +      Print the name of the current branch. In detached HEAD state,
 +      nothing is printed.
 +
  -v::
  -vv::
  --verbose::
index 877e5f503a66145912886c14917f0e68512e6284,d32f2eb611fe894dc4d99895fbab9527255d23c9..964f912d29ee92d55a3c98d40cc41941e7db743a
@@@ -242,8 -242,6 +242,8 @@@ should result in deletion of the path)
  +
  When checking out paths from the index, this option lets you recreate
  the conflicted merge in the specified paths.
 ++
 +When switching branches with `--merge`, staged changes may be lost.
  
  --conflict=<style>::
        The same as --merge option above, but changes the way the
  This means that you can use `git checkout -p` to selectively discard
  edits from your current working tree. See the ``Interactive Mode''
  section of linkgit:git-add[1] to learn how to operate the `--patch` mode.
 ++
 +Note that this option uses the no overlay mode by default (see also
 +`--[no-]overlay`), and currently doesn't support overlay mode.
  
  --ignore-other-worktrees::
        `git checkout` refuses when the wanted ref is already checked
        Do not attempt to create a branch if a remote tracking branch
        of the same name exists.
  
 +--[no-]overlay::
 +      In the default overlay mode, `git checkout` never
 +      removes files from the index or the working tree.  When
 +      specifying `--no-overlay`, files that appear in the index and
 +      working tree, but not in <tree-ish> are removed, to make them
 +      match <tree-ish> exactly.
 +
  <branch>::
        Branch to checkout; if it refers to a branch (i.e., a name that,
        when prepended with "refs/heads/", is a valid ref), then that
@@@ -313,6 -301,10 +313,10 @@@ leave out at most one of `A` and `B`, i
  <start_point>::
        The name of a commit at which to start the new branch; see
        linkgit:git-branch[1] for details. Defaults to HEAD.
+ +
+ As a special case, you may use `"A...B"` as a shortcut for the
+ merge base of `A` and `B` if there is exactly one merge base. You can
+ leave out at most one of `A` and `B`, in which case it defaults to `HEAD`.
  
  <tree-ish>::
        Tree to checkout from (when paths are given). If not specified,
diff --combined branch.c
index 643694542a51634e0bc5cbef92226913d16ccbe7,a84c8aaca2d3c563d167e25c6a3add950ec85a6c..a594cc23e25458250885244f477a5d4879df2537
+++ b/branch.c
@@@ -5,7 -5,6 +5,7 @@@
  #include "refs.h"
  #include "refspec.h"
  #include "remote.h"
 +#include "sequencer.h"
  #include "commit.h"
  #include "worktree.h"
  
@@@ -269,7 -268,7 +269,7 @@@ void create_branch(struct repository *r
        }
  
        real_ref = NULL;
-       if (get_oid(start_name, &oid)) {
+       if (get_oid_mb(start_name, &oid)) {
                if (explicit_tracking) {
                        if (advice_set_upstream_failure) {
                                error(_(upstream_missing), start_name);
  
  void remove_branch_state(struct repository *r)
  {
 -      unlink(git_path_cherry_pick_head(r));
 -      unlink(git_path_revert_head(r));
 +      sequencer_post_commit_cleanup(r);
        unlink(git_path_merge_head(r));
        unlink(git_path_merge_rr(r));
        unlink(git_path_merge_msg(r));
diff --combined t/t3200-branch.sh
index e9ad50b66dece121464f0638d5a4a1dd0280d121,acb16b62dda3abd87bfaad7658390c683b15e176..e9d7084d19c9d650f43f97d1c389c7fbc4cc51d2
@@@ -42,6 -42,10 +42,10 @@@ test_expect_success 'git branch a/b/c s
        git branch a/b/c && test_path_is_file .git/refs/heads/a/b/c
  '
  
+ test_expect_success 'git branch mb master... should create a branch' '
+       git branch mb master... && test_path_is_file .git/refs/heads/mb
+ '
  test_expect_success 'git branch HEAD should fail' '
        test_must_fail git branch HEAD
  '
@@@ -264,30 -268,6 +268,30 @@@ test_expect_success 'git branch --list 
        test_must_fail git rev-parse refs/heads/t
  '
  
 +test_expect_success 'deleting checked-out branch from repo that is a submodule' '
 +      test_when_finished "rm -rf repo1 repo2" &&
 +
 +      git init repo1 &&
 +      git init repo1/sub &&
 +      test_commit -C repo1/sub x &&
 +      git -C repo1 submodule add ./sub &&
 +      git -C repo1 commit -m "adding sub" &&
 +
 +      git clone --recurse-submodules repo1 repo2 &&
 +      git -C repo2/sub checkout -b work &&
 +      test_must_fail git -C repo2/sub branch -D work
 +'
 +
 +test_expect_success 'bare main worktree has HEAD at branch deleted by secondary worktree' '
 +      test_when_finished "rm -rf nonbare base secondary" &&
 +
 +      git init nonbare &&
 +      test_commit -C nonbare x &&
 +      git clone --bare nonbare bare &&
 +      git -C bare worktree add --detach ../secondary master &&
 +      git -C secondary branch -D master
 +'
 +
  test_expect_success 'git branch --list -v with --abbrev' '
        test_when_finished "git branch -D t" &&
        git branch t &&
  test_expect_success 'git branch --column' '
        COLUMNS=81 git branch --column=column >actual &&
        cat >expected <<\EOF &&
-   a/b/c     bam       foo       l       * master    n         o/p       r
-   abc       bar       j/k       m/m       master2   o/o       q
+   a/b/c     bam       foo       l       * master    mb        o/o       q
+   abc       bar       j/k       m/m       master2   n         o/p       r
  EOF
        test_cmp expected actual
  '
@@@ -339,6 -319,7 +343,7 @@@ test_expect_success 'git branch --colum
    m/m
  * master
    master2
+   mb
    n
    o/o
    o/p
@@@ -356,8 -337,8 +361,8 @@@ test_expect_success 'git branch with co
        git config --unset column.branch &&
        git config --unset column.ui &&
        cat >expected <<\EOF &&
-   a/b/c   bam   foo   l   * master    n     o/p   r
-   abc     bar   j/k   m/m   master2   o/o   q
+   a/b/c   bam   foo   l   * master    mb   o/o   q
+   abc     bar   j/k   m/m   master2   n    o/p   r
  EOF
        test_cmp expected actual
  '
@@@ -381,6 -362,7 +386,7 @@@ test_expect_success 'git branch -v wit
    m/m
  * master
    master2
+   mb
    n
    o/o
    o/p