Ashley Coolman
Ashley Coolman

Reputation: 11585

Include original commits with squashed commit when pushing to remote?

Question

What is a good way to ensure the remote has the commits that are within a squashed commit intended for a PR?

Background

I'm using Github, and squashing my commits into a single feature commit before pushing to origin.

If I push only the squashed commit, Github (aka the git blob on the remote) doesn't seem to know about the individual pre-squash commits (Github-markdown will usually convert [<commitSHA>] to a link to the commit, but this is not happening)

I'm guessing I could push my unsquashed branch, then delete it from origin. Then squash my commits, and re-push. But that seems a bit error prone.

Ideally it would be nice to have a git push argument that would examine the reflog to understand what commits went into a squashed commit and include them.

Note Also open to comments on the saneness of this workflow

Upvotes: 0

Views: 157

Answers (2)

Mark Adelsberger
Mark Adelsberger

Reputation: 45649

A couple notes:

1) In normal workflows, the act of "squashing" commits means that you are saying "these individual commits are unimportant; I created them as part of my development workflow but in the recorded history I want them understood as a single commit". By referencing the individual commits, you are working against yourself.

2) In spite of (1), you can preserve the original commits. However, they will not be understood by git as related to the squashed commit, or to your branch, or to any subsequent work. Host features (like Github's commit links) may indeed work, but if a state of the code is important enough to deserve such a link then I question the wisdom of removing it from the branch history.

3) With (1) and (2) in mind, an alternative is to just use true merges instead of squash merges. This will enable the default behaviors of the tools to work as intended and you won't have to take special steps to get your individual commits recognized on origin. Of course you think you don't want to do that, because it keeps the individual commits in the default log output. However, that is why the log command has the --first-parent argument.

4) If in spite of this you decide you just have to use squash merges and push the original commits under separate refs, it will work. But contrary to the speculation in your question, it is not then safe to delete the ref you used to push them. If you do, the individual commits may eventually be removed by garbage collection.

5) On the other hand, contrary to what nnovich-Oks answer seems to imply, you don't have to push before squashing, because squashing is not a destructive action.

So if you really want to, you can keep around the feature branches for individual commits, while using squashes to maintain a simplified master history, understanding that git will not recognize the relationship between all of these branches; that you cannot delete the feature branches because they're all that keeps the individual commits alive; and that you're going out of your way to solve a problem the hard way, cluttering your ref list with unused branches, all to do something that's built in to the git command set anyway.

Upvotes: 2

nnovich-OK
nnovich-OK

Reputation: 3163

Don't have much experience with github, but the following workflow looks relevant to your question.

  • create new branch for your work
  • push this branch to remote without squashing
  • when feature is ready, checkout main branch, perform merge feature_branch --squash and push it.

As a result, main branch has single commit with overall work, but one of its parents is branch with all development history. All commits are represented on remote, so linking should work fine.

Upvotes: 4

Related Questions