Zitrax
Zitrax

Reputation: 20314

Checking out orphan branch in new work-tree

I know that a new orphan branch can be created like so:

git checkout --orphan <new_branch>

however this uses my current work tree which I want to leave completely untouched. I tried:

git --work-tree=/tmp/test checkout --orphan <new_branch>

but this also seem to use my current work tree and not the one I specified using --work-tree.

I could use a second clone, but that does not seem optimal. Any way of solving this using work-trees?

Upvotes: 6

Views: 1325

Answers (4)

milahu
milahu

Reputation: 3599

git worktree add --orphan for git before version 2.42

this is based on cspotcode but does not create an extra empty commit

# https://unix.stackexchange.com/a/567537
function version_greater_equal() {
  printf '%s\n%s\n' "$2" "$1" |
  sort --check=quiet --version-sort
}

git_version=$(git version)
git_version=${git_version/'git version '/}

# https://stackoverflow.com/a/79220337/10440128
function git_worktree_add_orphan() {
  # global git_version
  local path="$1"
  local branch="$2"
  if version_greater_equal "$git_version" 2.42; then
    # this requires git version 2.42
    git worktree add --orphan "$path" "$branch"
    return $?
  fi
  # this also works before git version 2.42
  git worktree add --detach --no-checkout "$path" || return $?
  local empty_tree=$(git hash-object -w -t tree /dev/null)
  local empty_commit=$(git commit-tree "$empty_tree" -m "empty tree")
  git -C "$path" checkout --orphan "$branch" "$empty_commit"
}

if false; then
  # example use
  git_worktree_add_orphan some-path some-branch
fi

Upvotes: 0

VonC
VonC

Reputation: 1328122

With Git 2.42 (Q3 2023), 'git worktree add'(man) learned how to create a worktree based on an orphaned branch with --orphan.

So this should be supported.

See commit 926c40d, commit 128e549, commit 35f0383, commit 7ab8918, commit 9ccdace, commit ed6db0e, commit 1b28fbd, commit b71f919 (17 May 2023) by Jacob Abel (0xnu11pwn).
(Merged by Junio C Hamano -- gitster -- in commit 4dd0469, 22 Jun 2023)

worktree add: introduce "try --orphan" hint

Signed-off-by: Jacob Abel

Add a new advice/hint in git worktree add(man) for when the user tries to create a new worktree from a reference that doesn't exist.

Current Behavior:

% git init foo
Initialized empty Git repository in /path/to/foo/
% touch file
% git -C foo commit -q -a -m "test commit"
% git -C foo switch --orphan norefbranch
% git -C foo worktree add newbranch/
Preparing worktree (new branch 'newbranch')
fatal: invalid reference: HEAD
%

New Behavior:

% git init --bare foo
Initialized empty Git repository in /path/to/foo/
% touch file
% git -C foo commit -q -a -m "test commit"
% git -C foo switch --orphan norefbranch
% git -C foo worktree add newbranch/
Preparing worktree (new branch 'newbranch')
hint: If you meant to create a worktree containing a new orphan branch
hint: (branch with no commits) for this repository, you can do so
hint: using the --orphan option:
hint:
hint:   git worktree add --orphan newbranch/
hint:
hint: Disable this message with "git config advice.worktreeAddOrphan false"
fatal: invalid reference: HEAD
% git -C foo worktree add -b newbranch2 new_wt/
Preparing worktree (new branch 'newbranch')
hint: If you meant to create a worktree containing a new orphan branch
hint: (branch with no commits) for this repository, you can do so
hint: using the --orphan option:
hint:
hint:   git worktree add --orphan -b newbranch2 new_wt/
hint:
hint: Disable this message with "git config advice.worktreeAddOrphan false"
fatal: invalid reference: HEAD
%

git config now includes in its man page:

worktreeAddOrphan

Advice shown when a user tries to create a worktree from an invalid reference, to instruct how to create a new orphan branch instead.

Upvotes: 3

max630
max630

Reputation: 9248

Make a worktree with detached head then orphan it:

git worktree add --detach /.../dir
cd /.../dir
git checkout --orphan branch

Upvotes: 14

ElpieKay
ElpieKay

Reputation: 30928

You can try git-worktree.

git checkout --orphan <new_branch>
git commit
git worktree add /tmp/test <new_branch>

# switch to the previous branch
git checkout -
# or
git checkout <previous_branch>

cd /tmp/test
# do something to <new_branch>

Now /tmp/test is a sub worktree. It shares the same .git with the main worktree. If you don't need the sub worktree any more, you can simply remove /tmp/test. The new commits are stored in the main repository.

If your Git does not support git-worktree yet, you need a newer version.

Upvotes: 3

Related Questions