1. Problem scenario

Multiple people working on the same remote branch can have the following problems when pushing code:

$ git push origin master

# The result is as follows
To github.com:hello/demo.git
 ! [rejected]        master -> master (fetch first)
error: failed to push some refs to '[email protected]:hello/demo.git'
hint: Updates were rejected because the remote contains work that you do
hint: not have locally. This is usually caused by another repository pushing
hint: to the same ref. You may want to first integrate the remote changes
hint: (e.g., 'git pull ... ') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.
Copy the code

It can be seen from the output that a new COMMIT is not synchronized to the local branch and cannot be pushed. In this case, we generally perform the following operations:

$ git pull origin master

# The result is as follows
remote: Counting objects: 2, done.
remote: Compressing objects: 100% (2/2), done.
remote: Total 2 (delta 1), reused 0 (delta 0)
Unpacking objects: 100% (2/2), done. From github.com:hello/demo 3824da0.. f318a05 master -> origin/master Merge made by the'recursive' strategy.
 one.md | 2 ++
 1 file changed, 2 insertions(+)
 
$ git push origin master

# The result is as follows
Enumerating objects: 10, done.
Counting objects: 100% (8/8), done.
Delta compression using up to 8 threads
Compressing objects: 100% (8/8), done.
Writing objects: 100% (8/8), 1.24 KiB | 1.24 MiB/s, done. Total 8 (delta 5), reused 0 (delta 0) To github.com:hello/demo.git f318a05.. 1aefef1 master -> masterCopy the code

Yes, the push succeeded, but now use git log to view the commit record:

$ git log

# The result is as follows
commit 1aefef1a2bedbd3ebd82db8dcf802011a35a9888 (HEAD -> master, origin/master, origin/HEAD)
Merge: 24cfa5c f318a05
Author: hello <[email protected]>
Date:   Tue Jul 23 09:53:47 2019 +0800

    Merge branch 'master'of github.com:hello/demo commit 24cfa5c3ad271e85ff0e64793bf2bcc9d700c233 Author: hello <[email protected]> Date: Tue Jul 23 09:50:06 2019 + 0800 feat: the new function to submit the commit f318a05b1a4cbc0a6cf8d7dc7d3fb99cbafb0363 Author: World <[email protected]> Date: Tue Jul 23 09:48:20 2019 +0800 Feat:Copy the code

Git pull Origin Master merge Commit git pull Origin Master Merge Commit If multiple people do this multiple times, the commit record will have many of these auto-generated merge Commits, which can be ugly.

2. Solutions

Git pull Origin Master –rebase git pull Origin Master — merge commit

$ git pull --rebase origin master

$ git push origin master
Copy the code

3. Project examples

Now use a sample project to demonstrate the use of the above commands. The project (directory name: Demo) has the following structure:

# Run the following command in the demo directory
$ ls

# The result is as follows
one.md  two.md

$ cat one.md

# The result is as follows
hello one

$ cat two.md

# The result is as follows
hello two
Copy the code

Two developers, A and B, use A remote branch (master) to develop together. (A) changed the one.md file, committed A commit and pushed it to the remote branch master:

$ cat one.md

# The result is as follows
hello one

new feature from one

$ git push origin master

# The result is as follows
Enumerating objects: 4, done.
Counting objects: 100% (4/4), done.
Delta compression using up to 8 threads
Compressing objects: 100% (4/4), done.
Writing objects: 100% (4/4), 1.24 KiB | 1.24 MiB/s, done. Total 4 (delta 3), reused 0 (delta 0) To github.com:hello/demo.git f318a05.. 1aefef1 master -> masterCopy the code

At this time, student B did not know and did not update the remote branch to the local. (2) alter 2.md file, also commit a commit and try to push to remote branch master:

$ cat two.md

# The result is as follows
hello two

new feature from two

$ git push origin master

# The result is as follows
To github.com:hello/demo.git
 ! [rejected]        master -> master (fetch first)
error: failed to push some refs to '[email protected]:hello/demo.git'
hint: Updates were rejected because the remote contains work that you do
hint: not have locally. This is usually caused by another repository pushing
hint: to the same ref. You may want to first integrate the remote changes
hint: (e.g., 'git pull ... ') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.
Copy the code

Error detected, unable to push. Run the following command:

$ git pull --rebase

$ git push origin master
Copy the code

Can successfully push.

4. Precautions

  • performgit pull --rebaseYou must keep the local directory clean. That is, the state cannot bemodifiedThe file. (there isUntracked filesIt doesn’t matter)
  • If a conflict occurs, you can manually resolve the conflict and continuerebaseOr you can give up this timerebase

4.1 performgit pull --rebaseYou must keep the local directory clean

  1. There aremodifiedStatus file

To change a local version controlled file, run the following command:

$ git pull --rebase

# The result is as follows
error: cannot pull with rebase: You have unstaged changes.
error: please commit or stash them.
Copy the code

The above error will occur and cannot be operated.

Now check the file status:

$ git status

# The result is as follows
On branch master
Your branch is ahead of 'origin/master' by 1 commit.
  (use "git push" to publish your local commits)

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

	modified:   two.md

no changes added to commit (use "git add" and/or "git commit -a")
Copy the code

There is a local file change that has not been submitted. There are two ways to do this:

  • If the change is complete, you can commit (commitA)
  • If the modification is not complete, you can store it first:git stash

Try git pull –rebase after you’ve done all of the above, and no more errors will be reported.

If you do the Git Stash operation, you can go back to the original working state with the Git Stash pop.

  1. There areUntracked files

Check local file status:

$ git status

# The result is as follows
On branch master
Your branch is ahead of 'origin/master' by 1 commit.
  (use "git push" to publish your local commits)

Untracked files:
  (use "git add <file>..." to include in what will be committed)

	three.md

no changes added to commit (use "git add" and/or "git commit -a")
Copy the code

If this is the case, git pull –rebase should not be a problem.

4.2 If a conflict occurs, you can manually resolve the conflict and continuerebaseOr you can give up this timerebase

In the example project above, if student A and student B modify the same file. Then it is very likely that there will be conflicts. When STUDENT B comes to execute the command, the following situation will occur:

$ git pull --rebase

# The result is as follows
remote: Counting objects: 6, done.
remote: Compressing objects: 100% (6/6), done.
remote: Total 6 (delta 1), reused 0 (delta 0)
Unpacking objects: 100% (6/6), done. From gitlab.lrts.me:fed/gitlab-merge 93a1a93.. 960b5fc master -> origin/master First, rewinding head to replay your work on top of it... Using index info to reconstruct a base tree... M one.md Falling back to patching base and 3-way merge... Auto-merging one.md CONFLICT (content): Merge conflictin one.md
error: Failed to merge inThe changes. Patch failed at 0001 feat: Hint: Use'git am --show-current-patch' to see the failed patch

Resolve all conflicts manually, mark them as resolved with
"git add/rm <conflicted_files>".then run "git rebase --continue".
You can instead skip this commit: run "git rebase --skip".
To abort and get back to the state before "git rebase", run "git rebase --abort".
Copy the code

In this case, manually open the one.md file to resolve the conflict, and then execute:

$ git add one.md

$ git rebase --continue
Copy the code

Solve problems.

You can also abort the rebase operation with git rebase –abort.

5. To summarize

Merge Commit: Merge Commit: Merge Commit: Merge Commit: Merge Commit: Merge COMMIT: Merge COMMIT: Merge COMMIT: Merge COMMIT

Save the files that have been changed locally
$ git stash

Synchronize the latest remote commit to the local base
$ git pull --rebase

Push local commit to remote
$ git push

# eject the locally stored file and continue to modify it
$ git stash pop
Copy the code