How can I copy the content of a branch to a new local branch?

GitBranch

Git Problem Overview


I have worked on a local branch and also pushed the changes to remote.

I want to revert the changes on that branch and do something else on it, but I don't want to lose the work completely. I was thinking of something like create a new branch locally and copy the old branch there, then I can revert the changes and continue working on the old branch.

Is there a better way than this maybe?

Git Solutions


Solution 1 - Git

git checkout old_branch
git branch new_branch

This will give you a new branch "new_branch" with the same state as "old_branch".

This command can be combined to the following:

git checkout -b new_branch old_branch

Solution 2 - Git

See second part (since Git 2.23, Q3 2019): git switch -c newBranch oldBranch


With Git 2.15 (Q4 2017), "git branch" learned "-c/-C" to create a new branch by copying an existing one.

See commit c8b2cec (18 Jun 2017) by Ævar Arnfjörð Bjarmason (avar).
See commit 52d59cc, commit 5463caa (18 Jun 2017) by Sahil Dua (sahildua2305).
(Merged by Junio C Hamano -- gitster -- in commit 3b48045, 03 Oct 2017)

> ## branch: add a --copy (-c) option to go with --move (-m) > > Add the ability to --copy a branch and its reflog and configuration, this uses the same underlying machinery as the --move (-m) option except the reflog and configuration is copied instead of being moved. > > This is useful for e.g. copying a topic branch to a new version, e.g. work to work-2 after submitting the work topic to the list, while preserving all the tracking info and other configuration that goes with the branch, and unlike --move keeping the other already-submitted branch around for reference.

Note: when copying a branch, you remain on your current branch.
As Junio C Hamano explains, the initial implementation of this new feature was modifying HEAD, which was not good:

> When creating a new branch B by copying the branch A that happens to be the current branch, it also updates HEAD to point at the new branch.
It probably was made this way because "git branch -c A B" piggybacked its implementation on "git branch -m A B", > > This does not match the usual expectation.
If I were sitting on a blue chair, and somebody comes and repaints it to red, I would accept ending up sitting on a chair that is now red (I am also OK to stand, instead, as there no longer is my favourite blue chair).
> > But if somebody creates a new red chair, modelling it after the blue chair I am sitting on, I do not expect to be booted off of the blue chair and ending up on sitting on the new red one.


Second part: with git 2.23 (Q3 2019), no need to use git branch or the old confusing git checkout: you have git switch.

git switch -c newBranch oldBranch

Solution 3 - Git

git branch copyOfMyBranch MyBranch

This avoids the potentially time-consuming and unnecessary act of checking out a branch. Recall that a checkout modifies the "working tree", which could take a long time if it is large or contains large files (images or videos, for example).

Solution 4 - Git

Given you requested better way options:

One potential flaw with copying branches is that you have to take care about git's fast-forward behaviour if you want to merge into the same parent, or re-introduce changes back into the original branch from the copy.

For instance if you have reverted some commits in the 'original' branch, but now you would like to re-introduce the changes you reverted to the original, you cannot simply merge the copied branch to the parent because git sees those commits already exist (even thought they are reverted later).

Maybe cherry-pick [commit-range] would work in this context & doesn't care about existing hashes shrugs

In my opinion though it would be better to do this.

  1. Create a new branch from current branch HEAD git branch [archive-branch-name]
  2. Find the commit you want to roll back to with git log
  3. Run git reset --head [commit-hash-from-#2]
  4. git push -f origin

Note that you start on the 'original' branch and do not change branches during the steps.

Or even more simply you could just do away with branching altogether and just revert the commits you want to revert, and revert the revert later if you need to

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionserengeti12View Question on Stackoverflow
Solution 1 - GitDaniel HilgarthView Answer on Stackoverflow
Solution 2 - GitVonCView Answer on Stackoverflow
Solution 3 - GitLyle ZView Answer on Stackoverflow
Solution 4 - GitScott AndersonView Answer on Stackoverflow