Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How Can I Make The Commit History Clean In Git When Sync Upstream's Commit?

Tags:

git

github

I have forked a repo from GitHub and made some commit on my master branch. And the upstream repo's master branch have some commits ahead of mine. So I need sync these commits.

$ git remote -v
origin  [email protected]:johnwatsondev/react-navigation.git (fetch)
origin  [email protected]:johnwatsondev/react-navigation.git (push)
upstream    https://github.com/react-community/react-navigation.git (fetch)
upstream    https://github.com/react-community/react-navigation.git (push)


$ git pull --rebase upstream master
From https://github.com/react-community/react-navigation
 * branch            master     -> FETCH_HEAD
First, rewinding head to replay your work on top of it...
Applying: Update: add logic for invoking back key pressed listener in CardStack.js and remove default process logic
Applying: Update: only android platform need process physical back key pressed event


$ git status
On branch master
Your branch and 'origin/master' have diverged,
and have 6 and 2 different commits each, respectively.
(use "git pull" to merge the remote branch into yours)

nothing to commit, working tree clean


$ git pull
Merge made by the 'recursive' strategy.


$ git status
On branch master
Your branch is ahead of 'origin/master' by 7 commits.
(use "git push" to publish your local commits)

nothing to commit, working tree clean

I got this ugly commit history in my origin repo's master branch below:

commit history ugly

How can I make a elegant OP to sync my origin repo's master branch to upstream's master branch without ugly duplicate commits and the Merge branch *** commit?
(PS: I have make some change in my origin repo's master branch)

like image 988
JohnWatsonDev Avatar asked Jan 29 '26 12:01

JohnWatsonDev


2 Answers

As answered in Squash my last X commits together using Git, you can squash the previous n commits into a single commit using

git rebase HEAD~n -i

When you run this command, a text editor will open, and you have to replace the pick in front of all n-1 commits you want to squash, with s. Please note that you have to do a force push after squashing. This way you can merge many commits into one.

like image 110
Dane Avatar answered Jan 31 '26 03:01

Dane


There are already lots of answers available on SO regarding how to reset a remote and local history, but I guess your question is more about how to avoid these ugly merge commits during a pull.

In general you don't want to use the default pull behavior when you want to keep a linear history, otherwise you get this ugly merge commits when there are both local and remote changes. You should get into the habit of using git pull -r to use rebase instead of merge strategy during pulls.

Of course you can also can make an alias for that or change the default pull behavior via pull.rebase=true or branch.master.rebase=true if you want to set this in a branch specific way. But git pull -r does some pretty magic stuff sometimes so I'm always wary in changing the default behavior.

The way I like to do it is to do an explicit fetch first via git fetch and only then do a git merge if it's a fast forward merge, or do a git rebase after reviewing the remote changes. This gives way more control. In fact git pull (in its default behavior) is basically a git fetch && git merge which is explains why you get a merge commit when there are new local and remote commits.

Of course you can also work on a local non-remote tracking branch and do explicit merges and rebases on the master branch.

like image 45
David Ongaro Avatar answered Jan 31 '26 03:01

David Ongaro