Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I reuse an existing branch name as a new branch?

Tags:

git

My intent was to have a dev branch that I would create feature branches off. Those feature branched would be merged into the dev branch and the dev branch would then be merged back to master. Some how I managed to screw that up and I left my dev branch behind, so here is what I now have.

enter image description here

I think after merging the password_rest_and_activation_support branch into master, I could just create a new "dev" branch, called "dev-new" or "development", but I seems like I should be able somehow reuse the "dev" name, but I am not sure how to do this. I was thinking of just deleting the existing dev branch and creating a new one? What the right way to do this, given that the dev branch is also on a remote?

like image 821
nPn Avatar asked Jan 09 '15 03:01

nPn


People also ask

Can you reuse a branch name in git?

You can always reuse that branch if you'd like or remove it.

Can branches be renamed?

Git Branch Rename Command The steps to change a git branch name are: Rename the Git branch locally with the git branch -m new-branch-name command. Push the new branch to your GitHub or GitLab repo. Delete the branch with the old name from your remote repo.


2 Answers

Fundamentally, branch names work like little sticky-note labels.

You may remove a label entirely:

git branch -d foo

This finds the label with the word "foo" on it (this label is stuck on one particular commit) and peels that label off and throws it (the label, again) away.1

Or, you may erase the name on a label and write a new name on it:

git branch -m old new

The label is still stuck on the same commit, but now it has a different name.

Or, you may move a label from one commit to another:

git branch -f moved 1f0c9447

The last argument here is a raw commit SHA-1, but you may use anything that locates some commit, such as another branch name.

There are some important differences between "delete and recreate", "rename", and "move", because these labels also retain history, of which commit they named before the last time they were moved. If you delete a label entirely, the history disappears too. If you rename a label, it retains its history, and if you move a label, it acquires a new history-entry because you moved it from one commit to another.

When you make a new commit, whatever branch you're on, that branch label moves automatically, to point to the new commit. This label-move is recorded in its history.

Use whichever option makes the most sense (do you want history retained or augmented, or do you just want it tossed out?).

(Note that when you create a new branch:

git branch new

you can supply a raw commit SHA-1, or anything that finds a commit. So git branch new existing will make new branch new pointing to the same commit as existing.)


The branch history is kept in each branch's "reflog". There's a ref-log for HEAD as well, and git reflog shows you that one, but git reflog show foo shows the history for reference (usually, branch) foo.

This history is normally kept for 90 days.2 Furthermore, it's purely local: it does not get copied on git clone and git fetch, nor pushed with git push.


As a side note, tags are almost exactly the same as branches, with two big differences other than just the word "tag": they're never supposed to move (and won't move automatically), and they don't record a history (because they're not supposed to need one). "Remote branches", aka remote-tracking branches, are a bit of a cross between these. You don't move them, not even by making commits, but they do move: when your git contacts the remote and picks up new commits, it also picks up branch-label moves, and updates your remote-tracking branches and their reflogs.


1You can do this at any time with any label (with -D, uppercase), but if you remove the last label that finds some commit(s), those commits go invisible—you won't see them in gitk --all displays any more, for instance—and eventually (after about a month) they will get garbage-collected.

2As usual with git, it's actually a lot more complicated than that: there are two different reflog expiry values, one for "reachable" objects and one for "unreachable" objects. The 90 day default is for reachable objects; unreachable objects default to 30 days; and both values can be configured.

In addition, the special stash ref (used by git stash) has its default expiry set to "never", so that stashes don't expire.

like image 74
torek Avatar answered Sep 25 '22 19:09

torek


git checkout master 
git branch -D dev

(forcefully delete local dev)

git push origin :dev

(delete remote dev)

git checkout -b dev

(create a new local dev branch)

git push origin dev

(push new dev to origin)

For some non-destructive options, including branch renaming, see torek's answer.

like image 20
isherwood Avatar answered Sep 22 '22 19:09

isherwood