Reputation: 6255
as part of my job i use to make deploys between our enviroments dev/test/prod
We use to manage our code with the well known branching flow, so we have the following branch:
dev -> where all branches get merged to as a single commit when a feature is implemented
test -> where we use to test our code by using the platform
master -> this branch is actually used only for creating tags which will be then used in our production server
Recently i wanted to find a way to keep the code history as clean as possible, but i'm struggling on how to do that easily.
i created a repository and reproduced a flow so that you can understand why i'm struggling
so, after the initial commit i created the 2 branches dev and test and switched to dev to make the following commits and made 3 commits:
9e76b6d - koop4: added anawesome feature that makes life easier
44976b1 - koop4: added anawesome feature that makes life faster
64ea9d3 - koop4: added anawesome feature that makes life brighter
I made a pull request to bring those feature in test and squash-merge them with a singe commit. I also like to paste as a comment the results of the git command
git log --pretty=format:"%h - %an: %s" test..dev
Sometimes it happens that more features go through this cycle until everything is ready for production. Let's avoid redundacy and let's move to prod with another pull request!
Note: in prod we use to use as commit message the tag name
We did it! We now have a super clean history in all our environment! Great!
So, what's the poblem? Let's now repeat the cycle by adding new commits in dev:
ca215e8 - koop4: this will make you shit your pants
9e76b6d - koop4: added a scary feature that make us freak out
let create the pull request and ...Wait...what??? Why does it says i m still missing these commits:
Ok ok, I understand the concept, but a this point I think you realized my struggling. To keep my history clean i have to pick by myself the commits i need:
and even repeat the process for our master pull request.
In the end with some plumbing i can get to a great history for all enviroments, but when things start to grow i struggle understanding which commits i have to put in the commit comment to keep it clean.
Is there anyone with suggestion to keep a clean history without having to struggle that much?
Upvotes: 0
Views: 1024
Reputation: 487725
Half the problem is that you're using the GitHub Web GUI interface. :-) (I'm half-kidding about this being half the problem,1 but in fact, it's hiding an important detail.)
The other half of the problem is that you are using a so-called "squash merge", which is not a merge. See this answer for details.
When you do use a squash "merge", the effect is that you must abandon the commits that are now squashed. Those old commit(s)—there may have been many, as is the case with the three in your example—have been supplanted by a single new commit. (You can and should then fetch that commit into your own Git's origin/test
, since you made it through the GitHub GUI interface rather than the more sensible method of making it in your own repository, on your own test
branch, and then pushing that new commit directly.)
One easy way to abandon those commits is to abandon your own test
branch entirely, e.g., just delete it. Your Git won't know that this is a safe thing to do, so you would have to force-delete it. You would also have to be on some other branch, since you cannot delete your current branch. Then you can create a new branch using the same name test
, but pointing to your updated origin/test
as its upstream. Now you have in your local test
the single replacement commit (and all earlier commits) instead of the three commits (and all earlier commits).
That particular method requires at least two, and usually three Git commands, though: git checkout dev
(to get off test
), git branch -D test
(to dangerously and forcibly delete test
), and git checkout -b test
(to re-create test
). You can use just one dangerous Git command instead: git reset --hard origin/test
(again, after running git fetch
to get origin/test
updated).
All of the above is annoying and unnecessary. Simply avoid the GUI. When you have the test
branch working the way you want, do your own interactive rebase, and squash all three commits into one
$ git rebase -i
Edit the three pick
commands so that the first is pick
and the last two are squash
, write the file, and exit the editor. Then in the new editor session, edit the commit message into the "nice" (single-commit) version. Note that there is no need to keep the raw hash IDs of the original three commits—they will never be useful in the future—nor even any of the text messages from those commits: you can construct an all-new, improved commit message.
You will now have, on your own test
branch (and nowhere else), the squashed commit. You can now git push origin test
to push it to the GitHub repository.
You will also have to do something to kill off your outstanding pull request as being closed by the pushed replacement commit. Since I don't use GitHub that much, I'm not sure what that is. It might be as simple as including "closes #XX" in the commit message, or of course you can do it manually through their Web GUI.
1Does this make it 1/4 of the problem?
Upvotes: 2