Newbie workflow question - Constantly rebasing & Sync

Greetings.

At last, I am getting started with Git and GitHub. For the last years, I have exclusively used Mercurial, so distributed version control is not foreign to me. I believe I have understood the basic usage of Git - branches, remotes and rebasing.

Let’s consider my workflow:

  1. I have the repo MyCompany/App
  2. I want to work on something in a new branch newFeature, so I create a private fork MyName/App and start a new branch newFeature
  3. At the end of the day, I have a few commits like the following, and sync it to GitHub
c2
a3
a2
c1
a1
  1. The next day, I will work from elsewhere, and pull and check out MyName/App/newFeature
  2. I clean things up by rebasing so that history now looks like this
c12
a123
  1. I add another commit b1 between A and C and the history now looks like this:
c12
b1
a123
  1. I want to sync this back to Github to continue working on it somewhere later

But what should I do?
Should I delete MyName/App/newFeature and re-create it with what newFeature currently looks like on my disk?

Until now, I always create yet another branch newFeature-2 and push it there.
After a week, I am already on newFeature-4 and I am not sure if this is the right way to do it.

With Mercurial, this was very easy and clean, as every branch was a repository by itself when it was managed as a “patch queue”. As far as I understand, there is no native equivalent of patch queues in Git.

2 Likes

If you’ve rewritten history (which you have by flattening and adding an intermediate commit) then you have to tell git push that you really do want to rewrite the remote history (on your fork) so you’d do git push --force.

(This assumes that your fork is origin and the company repo is upstream. Although neither is specifically called out here, I just wanted my assumption and experience clear.)

2 Likes

If you want to modify the history of a branch, you’ll generally need to “force push”: git push --force ... This is a potentially destructive operation, which is why Git refuses to do it without the --force option. :warning:

By default a push to an existing branch will accept only commits that are added on top of the current branch, it will not delete existing commits. However, a rebase effectively does just that: It replaces the commits you modify and their descendants with the modified version, and deletes the old version. So if you want to push the rebased branch, you need to disable the “don’t delete commits on the remote branch” using --force. I highly recommend double-checking if what you’re about to force-push is correct, so you don’t accidentally delete remote commits that you actually want to keep. :slightly_smiling_face:

Note that the same principle also applies to pulling the rebased branch somewhere else: A git pull will not replace the local branch. By default it would try to merge the diverged history, which is probably not what you want if you have rebased the remote branch. To replace the local branch with the remote one, you can either git reset the local branch to the remote one, or just delete the local branch and check out the remote one again.

3 Likes

Thank you both very much.

I was not aware that rewriting history on a remote was even possible. As I said, I am coming from Mercurial where a commit is permanent after it has been pushed somewhere.

I think I will just play around a bit to see how it feels.

Thanks again!

2 Likes