git log master..HEAD
In the past, I have found myself a bit afraid to fully use git, because git history is something so painful to rewrite, especially when the repo is shared by other users. Besides, it just seems bad practice (and it is) to rewrite history.
With true code, my concerns are a bit alleviated because most of the time you can test that locally. The situation I’m referring to is using git as a deployment mechanism for servers. Let me walk you through my old thought process.
I want to try a new change for particular server type. I have two options. I can just log into the server and try out my change, hoping the one that I commit as a "copy-paste" later into the git repo works identically, or I can make the change inside the git repo, push it upstream, triggering the test deployment, which I can (and should) test with. However, what if the change doesn’t work? I can fix it sure, but I’ll muck up the history with unecessary "Broke it…fixed it" commits, and removing those will require rewriting history.
Git is well known for its "cheap branching". Because it makes it so easy to rebase and merge onto any given branch.
Firstly, find the first commit of your branch. We’ll assume that this branch
came off of master and that we are currently working inside this branch (if
git checkout <branchname>)
git log master..HEAD
That command will give you a list of all commits that have happened on your feature branch ahead of the master branch. Assuming someone hasn’t rewritten history (which has happened to me before…ugh), you should be looking at only your branch’s commits. Scroll to the bottom and copy the commit id for the very first commit in the series.
git rebase -i <commit_id>^1
Don’t forget the "carrot 1" (
^1) at the end there, as it is very important.
We just told git to rebase the commit series on top of the most recent commit
from master (the "carrot 1" says "one commit before this commit", hence one
commit before your work started since you selected your first branch commit),
interractively. Iterractive mode gives us a chance to tell git how to handle
each commit, be it picking, squashing, editing, rewording, etc.
Running the interractive rebase should bring you into an editor with text that looks something like…
pick e57d408 Implemented new ifcfg profile functionality pick cd476e8 Fixed minor issue pick 96a112b Fixed another stupid issue pick 9741e2c Testing a small change pick ec32a51 Revert "Testing a small change" pick 5d61d26 Revert "Fixed another stupid issue" ...
Here we can change what we want to do with each commit as the rebase proceeds. In this case, I want to reduce my commit set down to one commit, the most recent (note in your set, the most recent is on the bottom).
pick e57d408 Implemented new ifcfg profile functionality s cd476e8 Fixed minor issue s 96a112b Fixed another stupid issue s 9741e2c Testing a small change s ec32a51 Revert "Testing a small change" s 5d61d26 Revert "Fixed another stupid issue" ...
It doesnt matter what the commit messages are at this point. When the time comes to merge the commits, you’ll get a chance to rewrite the commit message.