0

I have a Git repository which I have started to develop on master branch in and now I believe that master shouldn't be a long running branch. As others, I think master branch always holds the stable product.

So, I would like to open a new branch named develop and that branch will be a long running development branch but I am not sure what would be the best approach to switch here. My current solution is this:

Open up the new branch and push it to GitHub:

git checkout -b develop
git push origin develop

Then get back to master branch and stop tracking all the files except for README.md and push it to remote repository (GitHub, in this case):

git checkout master
git rm . --cached -r
git add README.md
git commit -m "cleaned up the master branch"
git push origin master

What are your thoughts?

tugberk
  • 57,477
  • 67
  • 243
  • 335
  • This doesn't make any sense. Could you explain what you're trying to accomplish be blanking out your `master` branch? This has nothing to do with making it stable, it just makes it empty and useless. I'm also confused by what you mean by "long running" branches. Master should be the *longest* running branch. By convention, it should be the only branch that always exists throughout the history of your project. – user229044 Apr 04 '12 at 12:01
  • @meagar I think I explained what I am after: *master shouldn't be a long running branch. As others, I think master branch always holds the stable product.*. By *long running*, I meant development branch. – tugberk Apr 04 '12 at 12:06
  • The *master* branch can and should hold the stable product, but that means (as I said) that it should be the *longest running branch*. It should always exist, while your development and feature branches merge and fork and disappear. – user229044 Apr 04 '12 at 12:08
  • @meagar Of course, master always be there but by holding the latest production code. Say you have a *dev* branch and 10 feature branches. The feature branches will be merged into *dev* branch and when the dev branch is ready for prod, it will be merged into master branch. After the prod, the development will continue on dev branch. This is what I am applying here. – tugberk Apr 04 '12 at 12:12
  • I agree completely, this is exactly the flow you should use. What does *removing all files from master* have to do with the above scenario? That is the part I have issue with, and the part I am trying to talk you out of. That doesn't make sense and it is not how Git works. Those files aren't dangerous or "untidy", removing them just breaks your master branch and creates tremendous merge headaches down the road. – user229044 Apr 04 '12 at 12:13
  • @meagar simple. Current code under the master is unstable for now. If I were starting this project today, I would start developing under develop branch. The main question here is this: is it too late to accomplish this in my current scenario? – tugberk Apr 04 '12 at 12:14
  • It's not "too late", but it is a nonsensical thing to do and you shouldn't do it for the sake of being "tidy" or "clean". If you really, *really* want to "reset" master to a blank state, you need to delete the branch. When you have "stable" code later on, you need to recreate the branch at its new stable state. Removing all the files from master won't accomplish this, it will only break your eventual merge. – user229044 Apr 04 '12 at 12:17
  • As someone who is extremely proficient with Git theory and practice, all I can do is advise you against this one final time. There is no reason to do what you're trying to do. Just stop using `master` and begin your development on `develop`. When your `develop` branch is stable, merge it into `master`. Very simple, very clean, and the way Git is meant to work. – user229044 Apr 04 '12 at 12:19
  • See my updated answer for a way of accomplishing what I think you're after – user229044 Apr 04 '12 at 12:41

3 Answers3

2

Your problem is with the NAME "master".

A branch is a branch. None of them is really more important than any other. The name is literally just a tag--a string that identifies the current HEAD, and bumps along as that HEAD is committed on top of. But a branch's "master"-ness is only important because that's the name git gives the first branch it creates in a project. But that's just a name. Let's take your current master branch and give it a new name. Since what you call it is irrelevant, let's choose "steve".

git branch -m master steve

Great. Now you HAVE no master branch! But you have the old steve branch that has historical work in it. That's worth having around, but because you're drawing a line in the sand in the history right now, you'll likely never dip back into it.

So then check out your dev branch, work on it, etc. And when it's stable (whatever that means in your particular case), create yourself a NEW master

git checkout -b master

Ha ha! First commit on that master branch is stable, and you can make sure all future commits are too! (BTW you'll want --no-ff on all merges from devel into master, to keep those intermediate potentially nonstable commits out of your shiny new "master" branch.)

Dan Ray
  • 21,623
  • 6
  • 63
  • 87
  • 2
    +1; This was probably a better (more patient) way of explaining things. @tugberk As a side note, if it's "historically" unstable code that you want to keep out of master, (ie, every commit on master should be stable) this is impossible. Master will (when you `git checkout -b master`) contain every development commit you've done on `develop` (or `steve` in this case). You can't keep "unstable" stuff out of master in that sense. Branches just don't work this way in Git. – user229044 Apr 04 '12 at 12:28
  • @maegar - Shh! I was trying to have him not notice that! ;-) – Dan Ray Apr 04 '12 at 12:33
1

That's not at all how branches work in Git. There is no reason to remove all your files from master, and indeed, this will render master totally useless for later merging. You'll be forcing your master and develop branches to diverge in a fundamental way.

Just checkout your develop branch, and do your development work there. When it's deemed "stable", checkout master and git merge develop to bring your stable code into master. Then push both branches.

You should also modify your git push origin develop to include -u to automatically --set-upstream for your develop branch, allowing you to push and pull changes:

git push -u origin develop

As an addendum to Dan Ray's answer, if you really want to retroactively make master empty until you git merge --no-ff develop, you need to destroy master, and (now or when you're ready to merge) recreate it to point at the earliest commit in your repo. Then master and develop will have diverged at the earliest possible moment, and they can be merged giving the illusion that "master was always stable":

  • checkout your develop branch: git checkout -b develop
  • delete master: git branch -d master
  • find the earliest commit in your repository via git log
  • recreate master at that early point in time: git branch master <early commit id>
  • eventually merge into master: git checkout master && git merge --no-ff develop

Now your master branch has "always" been empty, until your development code was merged in.

Community
  • 1
  • 1
user229044
  • 232,980
  • 40
  • 330
  • 338
  • This doesn't solve my main issue. I do not want stable code to be in my master branch. My current code is unstable in master is unstable and not ready for development. I am not sure if you get what I am after here. – tugberk Apr 04 '12 at 12:04
  • This doesn't make sense. There is nothing *wrong* with having unstable code in master during early development. Just stop doing your development work there and then, when you're ready, merge your stable stuff back in. Removing all the files doesn't make any sense. You'd be better of just deleting the `master` branch completely, and then recreating it when you consider your code "stable". – user229044 Apr 04 '12 at 12:06
  • This may not make sense to you but it does very well for me. I believe the master branch always holds the stable code and I am after this here. – tugberk Apr 04 '12 at 12:08
  • **I agree**. The issue isn't about `master` holding the stable code, *it should*. The issue is that you *fundamentally* misunderstand what that means and how Git works. Blanking out master to make it "stable" is nonsense, that isn't how Git works. Just *stop using it*, stop committing to it, stop deploying from it, and work on feature/development branches. When you're done with your development work, merge your changes back in to master. This is how Git works. There is no reason to remove your files from master, that is a wrong and broken workflow. – user229044 Apr 04 '12 at 12:09
0

It sounds like what you want to do is a combination of creating a new develop branch from master and this answer for How to insert a commit as the first, shifting all the others?.

Let's say you have a history like the following:

$ git --version
git version 1.7.9.rc2.1.g69204
$ git log --oneline --decorate --all
3047e68 (HEAD, master) D
d5b5fdb C
4a26775 B
c53013b A
2a984b8 initial

Create a new develop branch from the master branch:

$ git branch develop
$ git log --oneline --decorate --all
3047e68 (HEAD, master, develop) D
d5b5fdb C
4a26775 B
c53013b A
2a984b8 initial

Create a new initial commit and set it up how you like:

$ git symbolic-ref HEAD refs/heads/newroot
$ git rm --cached -r .
$ git add README.md
$ git clean -f -d
$ git commit -m 'new initial'
$ git log --oneline --decorate --all
8b9881c (HEAD, newroot) new initial
3047e68 (master, develop) D
d5b5fdb C
4a26775 B
c53013b A
2a984b8 initial

Now make newroot the develop branch and the new initial commit the master branch:

$ git rebase --onto newroot newroot develop
$ git branch -d newroot
$ git log --oneline --decorate --all
3d589b6 (HEAD, develop) D
f6a83da C
6c8bdc9 B
f8dd99f A
79706b0 initial
8b9881c new initial
3047e68 (master) D
d5b5fdb C
4a26775 B
c53013b A
2a984b8 initial

Now, after you're certain you want to get rid of the existing master history and make the new initial commit master's HEAD:

$ git reset --hard 8b9881c
HEAD is now at 8b9881c new initial
$ git log --oneline --decorate --all
3d589b6 (develop) D
f6a83da C
6c8bdc9 B
f8dd99f A
79706b0 initial
8b9881c (HEAD, master) new initial

And when the develop branch is stable and ready for master:

$ git checkout master
$ git merge --no-ff develop
$ git log --oneline --graph --decorate --all
*   e8a5c32 (HEAD, master) Merge branch 'develop'
|\  
| * 3d589b6 (develop) D
| * f6a83da C
| * 6c8bdc9 B
| * f8dd99f A
| * 79706b0 initial
|/  
* 8b9881c new initial
Community
  • 1
  • 1
Go Dan
  • 15,194
  • 6
  • 41
  • 65