Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is squashing commits into one best practice (for this particular workflow)?

I have the following git workflow:

  1. Create new feature branch
  2. Work on feature branch
  3. Commit often
  4. Once feature is complete, merge into master branch
  5. Rinse and repeat

However, sometimes, I have the need to revert a whole feature from master. This could involve a whole lot of reverting. (The reason for needing to revert a feature is I have a website that works off of one repo. From there, we use a script that deploys the site to either our Production site or Staging site. Both are done from our master branch. Don't ask, that's just what I've been given to work with. Sometimes, I'm working on something that I stage, but then an immediate change needs to be made, so I needed some way to pull my changes in order to clean the repo.)

I'm thinking that the easiest way to do so is if each feature branch has only one commit. Then I could revert that commit. So naturally, I am thinking of squashing all commits of a feature branch into one, prior to merging it into master.

So now my workflow would look like:

  1. Create new feature branch
  2. Work on feature branch
  3. Commit often
  4. Once feature is complete git rebase -i HEAD~number_of_commits (or if remote branch is available, origin/feature_branch)

Is there any issues with this logic? Does it go against any best practices? I did some testing myself and the whole workflow seems to run smoothly and solves my problem, but I wanted to run the idea by other (smarter) Git-ers to see if there is anything wrong with it.

Thanks!

like image 504
Fillip Peyton Avatar asked May 08 '13 19:05

Fillip Peyton


People also ask

Is squashing commits best practice?

Before you start, keep in mind that you should squash your commits BEFORE you ever push your changes to a remote repository. If you rewrite your history once others have made changes to it, you're asking for trouble… or conflicts. Potentially lots of them!

What is the point of squashing commits?

Squashing is a way to rewrite your commit history; this action helps to clean up and simplify your commit history before sharing your work with team members. Squashing a commit in Git means that you are taking the changes from one commit and adding them to the Parent Commit.

Should I use squash commit?

Squash merges, as it's proponents argue, are more valuable than merge commits because entire new features or bug fixes can be compressed into a single commit and therefore easier to code review and read at some point in the future.


2 Answers

You should look at leveraging the squash merge capability of git i.e. git merge --squash, so that you do not rewrite history unnecessarily.

Both git merge --squash and git rebase --interactive can be used to produce a squashed commit with the same resultant work-tree, but they are intended to serve 2 totally different purposes. Your tree eventually ends up looking different in both the cases.

Initial tree:

a -- b -- c -- d    master
      \
       \-- e -- f   feature1

After git checkout master; git merge --squash feature1; git commit:

a -- b -- c -- d -- F    master
      \
       \-- e -- f   feature1

After git checkout master; git rebase -i feature1 and choosing to pick c and squash d:

a -- b            /-- F  master
      \          /
       \-- e -- f   feature1

As you can see from the difference, you do not rewrite the history of any branch when using git merge --squash but you end up rewriting the history of master when using git rebase -i.

Also note that the actual commits (for the ones which got squashed) would be present in your git history in both the cases, only as long as you have some branch or tag reference through which those commits are reachable.

In other words, in the above example, if you delete feature1 after doing merge --squash, you would not be able to actually view the commits e or f in the future (especially after the 90 days reflog period). The same applies to the commits c and d in the rebase example.

like image 152
Tuxdude Avatar answered Sep 18 '22 14:09

Tuxdude


One specific downside to your approach is that it severely reduces the utility of git bisect in tracking down bugs in your code.

That said, if you find yourself reverting an entire feature often enough to where you're looking for ways to optimize that process, you may want to ask yourself whether you're merging into master too quickly. You may want to consider using multiple long-running branches to set up a workflow that suits your project better.

like image 45
Wally Altman Avatar answered Sep 17 '22 14:09

Wally Altman