Question

(There's a lot of similar questions on this, and I've also read through various docs, but I can't find anything answering this specific issue.)

Given a repository with no remotes and no branches, with 20 commits on master.

The intent is to end up with an empty master, and all the commits on develop, but without a messy history.

Is there a difference between:

git branch --move master develop
git checkout --orphan master

And:

git checkout -b develop 
git merge master
git checkout master
git reset --hard HEAD^20

?

The first option seems the simplest way to do this, but I've not seen it suggested anywhere - all the various things I've been reading tend to use variants of the second option (or rebasing, which I don't think applies here).

Does the first option do what I think it does, and does it have any benefits/drawbacks compared to the second option?

Is there an alternative even better way to achieve this?

Was it helpful?

Solution

Branches are just commit pointers. You get into some weird territory when there's nothing at which to point. Honestly if you're just looking to get a "clean" workflow history, so the first commit of any significance is a merge from develop into master, add an insignificant commit to master first:

git branch --move master develop
git checkout --orphan master
git rm -rf . ;# abandon the staged, orphaned changes
echo README > README ;# put something in this working directory
git add README && git commit -m "Initial commit of <my_project>"

Why commit something? Because once you run the --orphan checkout, you won't be able to do anything meaningful with the master branch. Try it yourself:

$ git checkout --orphan master
Switched to a new branch 'master'
$ git checkout develop && git checkout master
error: pathspec 'master' did not match any file(s) known to git.

How about a merge?

$ git checkout --orphan master
Switched to a new branch 'master'
$ git merge develop
fatal: Non-fast-forward commit does not make sense into an empty head

No dice. The only real way around this is to commit something, anything, to that empty branch. The moment you do, you can merge develop any way you'd like:

$ git merge develop
Merge made by the 'recursive' strategy.
 README | 1 +
 1 file changed, 1 insertion(+)
 create mode 100644 README

And the log:

$ git log --graph --oneline
*   867a1f9 Merge branch 'develop'
|\  
| * 22df145 README
* 15ba82a Initial commit of test project

OTHER TIPS

The only problem I see is that the second version won't work. HEAD^20 won't resolve to anything on a history with only 20 commits, so git reset --hard HEAD^20 will fail.

Your initial version should work fine. If the second version had worked, I can't see there being a significant difference between the two.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top