Git for Recovering SVN/ClearCase/CVS/"Other Old School SCM Tool" Users
Git is really a great way to encourage sharing of code and contributions to projects. However, as a lot of folks out there, I came from a different background of SCM tools that really weren't as good as dealing with lots of parallel development tracks, branches, and multiple repository coding. If you are new to Git like I am, you might find the following info useful to demystifying git and find that git is fairly easy to work with if you have a better understanding of how it works.
I would first suggest you have a read of the freely available Pro Git. It gives you the basics of git, and also points out differences that you will see if you are coming from other SCM tools. You can read that online at http://git-scm.com/book or buy it for yourself.
One area of particular interest for me is the ability to combine multiple commits into a single commit. This feature is called "squashing" in git. It's important to me because I like to commit often. Committing often isn't a bad thing, but my problem is that I also make a lot of mistakes. So I've got a ton of those "fixing this feature that I'm working on" type commits in my repos. I don't want to expose my ignorance to the rest of the world (and it's just a heck of a lot harder to figure out what is going on with that huge mess of commits!), so I tend to squash them down to more manageable blocks of working code changes. You can do this interactively with git, and you can follow the section at http://git-scm.com/book/en/Git-Tools-Rewriting-History#Squashing-Commits specifically to deal with that situation.
When working with GitHub repos there is a standard etiquette to forking and submitting pull requests that you will want to follow to make it easier for people to accept your changes. You can review that process and it's associated steps at http://dret.typepad.com/dretblog/2013/02/github-fork-etiquette.html.
But what if you screwed up and made a lot of changes on the master branch? How do you get those changes into a feature branch, and wipe the slate clean? Well, if you were committing a lot of things locally, but hadn't pushed those changes to another repo (or your own on GitHub), it's fairly simple. You simply checkout a new feature branch, and then rebase your master branch to the commit before you started work. You can do the following on your master branch to set things right. Etiquette suggests that you name the branch after your git user name and the feature name, separated by a forward slash, but that is not a hard requirement. Here are the commands:
If no one has forked your repo, you can push your cleanup work to the remote repo using the following command:
It is worth noting that I had a little trouble with the push at this point because I was originally using the Mac GUI GitHub client to manage my repo. When I tried to push, I first got a 404 error on the command line. This was because my repo URL didn't have a ".git" on the end of it. So I corrected that with the following command (replace placeholders, of course):
At this point your changes have been removed from the master branch, but still reside in your feature branch. If you want to continue working in your feature branch, you'll need to switch to it with the following command (changing the branch name out for the one you created):
I would first suggest you have a read of the freely available Pro Git. It gives you the basics of git, and also points out differences that you will see if you are coming from other SCM tools. You can read that online at http://git-scm.com/book or buy it for yourself.
One area of particular interest for me is the ability to combine multiple commits into a single commit. This feature is called "squashing" in git. It's important to me because I like to commit often. Committing often isn't a bad thing, but my problem is that I also make a lot of mistakes. So I've got a ton of those "fixing this feature that I'm working on" type commits in my repos. I don't want to expose my ignorance to the rest of the world (and it's just a heck of a lot harder to figure out what is going on with that huge mess of commits!), so I tend to squash them down to more manageable blocks of working code changes. You can do this interactively with git, and you can follow the section at http://git-scm.com/book/en/Git-Tools-Rewriting-History#Squashing-Commits specifically to deal with that situation.
When working with GitHub repos there is a standard etiquette to forking and submitting pull requests that you will want to follow to make it easier for people to accept your changes. You can review that process and it's associated steps at http://dret.typepad.com/dretblog/2013/02/github-fork-etiquette.html.
But what if you screwed up and made a lot of changes on the master branch? How do you get those changes into a feature branch, and wipe the slate clean? Well, if you were committing a lot of things locally, but hadn't pushed those changes to another repo (or your own on GitHub), it's fairly simple. You simply checkout a new feature branch, and then rebase your master branch to the commit before you started work. You can do the following on your master branch to set things right. Etiquette suggests that you name the branch after your git user name and the feature name, separated by a forward slash, but that is not a hard requirement. Here are the commands:
git branch <your git user name>/<your feature name> git log # With the log command, you'll get a list of all the commits going backwards, so just get back to the commit that occurred just before you started working and then copy the commit SHA code. We'll use it in the next command. git reset --hard <SHA-1 of the commit you want to move back to>Now, this all works fine and good if you have not pushed anything to another repo (like your forked repo at GitHub). But if you have, you'll need to add a "--force" option to your git push command for just this one time. This can be very dangerous in some circumstances, but it fairly safe if no one else has pulled in your accidental changes to the master branch. That is usually true with your own personal forks, but you should probably check to see if anyone has forked your repo. On GitHub, you can simply click on the number next to the "Fork" button, and then click on the "Members" tab to see if anyone has forked your repo. If so, I'm not sure what the right solution is for that situation.
If no one has forked your repo, you can push your cleanup work to the remote repo using the following command:
git push --forceYour commits should now be removed from your own repo's copy of the master branch in all locations.
It is worth noting that I had a little trouble with the push at this point because I was originally using the Mac GUI GitHub client to manage my repo. When I tried to push, I first got a 404 error on the command line. This was because my repo URL didn't have a ".git" on the end of it. So I corrected that with the following command (replace placeholders, of course):
git remote set-url origin https://github.com/<your git user name>/<your git repo name>.gitYou can check the URLs of your remotes with the following:
git remote -vAt this point, I would get a 403 when I tried to push. Come to find out, I needed to tweak the URL that GitHub gave me for my repo to the following:
git remote set-url origin https://<your git user name>@github.com/<your git user name>/<your git repo name>.gitDoing that allowed me to push from the command line properly.
At this point your changes have been removed from the master branch, but still reside in your feature branch. If you want to continue working in your feature branch, you'll need to switch to it with the following command (changing the branch name out for the one you created):
git checkout <your git user name>/<your feature name>Hopefully you can see from the above info that you can work with git effectively, and that it can be a powerful tool for source control, even if you make a lot of mistakes like me.
Comments