Can I make origin/dev branch of origin/staging when origin/dev already exists?
I'd like to reclaim the dev branch, but it's filled with things we don't want to keep. Can I make it just stop being whatever it is now and be based of staging instead without deleting the history that's in it? I'd like to set things up like this:
staging __________________________________ dev _________ \______/ \____/
Depends on what you mean by "based off of staging" and "without deleting the history".
If you mean that you want to act like you merged dev and staging together, but actually have the end result be exactly what is currently in staging, that's easy. From the root directory of the repository:
git checkout origin/dev -b dev git merge --no-commit origin/staging git checkout --theirs . git commit -m "Revert back to the contents of staging" git push origin dev
The key line here is the third one. It's what overwrites the result of the merge with the exact contents of the origin/staging branch.
A branch is only a reference to a commit. If you feel like getting rid of the dev branch, then in your local repository do
$ git branch -D dev $ git branch dev staging
The first command deletes the branch "dev" and the second creates it again forking it off "staging" so that "dev" branch ends up pointing to the same commit "staging" does.
If you sync with a remote repo, you will need to do forced push of the new "dev" branch:
$ git push --force origin dev
If you still need to preserve the history "dev" contains now, rename it instead of deleting:
$ git branch -m dev ex-dev
The point about forced pushing the new "dev" obviously still holds in this case.
Note that forced replacement of a branch in the remote repository has significant repercussions for those who cloned the repo before such replacement and based their local branches on the original contents of he now-replaced branch. This is widely covered in the literature. See git-rebase manual for instance.
Your question's a little confusing in that it says "things we don't want to keep", but then "without deleting the history". To err on the side of caution, I would recommend:
git checkout staging #switch away from dev branch git branch -m dev olddev #rename old dev branch so we don't delete history git checkout -b dev staging # start a new dev branch where staging is currently
If you want to start the new dev branch at a different point, just substitute the appropriate SHA1 or branch name for staging in the last command. If you want dev to be a completely new branch with no parents, you'll need the --orphan option to git checkout.
Once you've done that, see kostix notes about pushing the new dev to an upstream repository.