What is git pull force - Overview
A git pull force procedure enables an update to a local repository with remote content even when you have pending commits. This is different from what a default git pull process does as it only allows the pull of remote data to a clean local repository without untracked commits. In case there are pending commits founds during a pull operation git will alert you to commit them before the merge is complete.
To forcefully pull remote commits to overwrite the local commits you will run the git reset --hard
command to the specific branch but this has dire consequences. Â You will lose all your local commits unless you back them up using git stash. Â Git stash will save your local changes to be later accessed after a force pull from the remote repository.
In this tutorial git pull force, we will learn how to run git pull force
with its repercussions and practising a safe force pull using examples.
git pull force workflow
1. Force overwrite untracked or committed changes from local repository
## Switch to your branch (if not already there) git checkout mybranch ## Verify your current branch git branch ## Backup your branch (optional) git branch backup-mybranch ## Fetch refs and tags from remote repository git fetch origin mybranch ## Reset HEAD position to fetched reference git reset --hard origin/mybranch ## Delete any untracked files and directories git clean -f -d ## Perform git pull to make sure there are no more issues git pull ## Delete backup branch git branch -d mybranch
2. Save local repository changes and perform git pull force
## Switch to your branch (if not already there) git checkout mybranch ## Verify your current branch git branch ## Backup your branch (optional) git branch backup-mybranch ## Stash your local repository changes. Changes must be un-tracked (i.e. not committed) git stash ## Verify your stashed list git stash list ## Fetch refs and tags from remote repository git fetch origin mybranch ## Reset HEAD position to fetched reference git reset --hard origin/mybranch ## Perform git pull to make sure there are no more issues git pull ## Bring back the stashed changes git stash pop ## Check the status git status ## Delete backup branch git branch -d mybranch
Performing git pull force in difference scenarios
We have a situation where in our team in a project. User deepak
and alisha
somehow end up modifying the same file. Now alisha
was quick enough to push her changes to remote repository but deepak
somehow realised that he has not pulled the latest changes from remote repo in quiet some time.
In this case, they both are working on git-example project under dev branch.
Example-1: git force pull to overwrite untracked changes from local repository
In this section we will demonstrate a scenario when the operator wants to overwrite his or his untracked changes from the local repository and perform git pull force:
Lab Environment
Here is a brief information about how our lab environment is setup. User alisha
has push changes as part of 4da8c06 commit ID:
alisha@ubuntu:~/git-example$ git log --oneline 4da8c06 (HEAD -> dev, origin/dev) Two d7b6c56 One 009bcfd (origin/main, origin/HEAD, main) Initial commit
While user deepak
has the following commit history:
In the mean while deepak
also has some un-committed changes in his local repository:
deepak@ubuntu:~/git-example$ git status
Sample Output:
Since the same file was also modified by Alisha
with 4da8c06
commit ID, hence the pull operation fails:
deepak@ubuntu:~/git-example$ git pull origin dev
remote: Enumerating objects: 5, done.
remote: Counting objects: 100% (5/5), done.
remote: Compressing objects: 100% (2/2), done.
remote: Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
Unpacking objects: 100% (3/3), 260 bytes | 260.00 KiB/s, done.
From gitlab.com:golinuxcloud/git-example
* branch dev -> FETCH_HEAD
d7b6c56..4da8c06 dev -> origin/dev
Updating d7b6c56..4da8c06
error: Your local changes to the following files would be overwritten by merge:
file1
Please commit your changes or stash them before you merge.
Aborting
In this situation we will assume that, deepak
wants to overwrite the local changes which he has not yet committed. Follow the below steps to perform a git pull force:
Step-1: Perform git fetch
As we have already covered in previous articles git pull performs git fetch + git merge which is the cause for such problems in most cases. So we can only perform git fetch first which will pull all the remote repo changes but it will NOT merge them to the local repository.
deepak@ubuntu:~/git-example$ git fetch origin dev
From gitlab.com:golinuxcloud/git-example
* branch dev -> FETCH_HEAD
As you can see from the commit history, as expected we don't have commit changes from alisha
here as they were only fetched but not merged:
deepak@ubuntu:~/git-example$ git log --oneline
Sample Output:
At this stage our uncommitted changes are still available:
deepak@ubuntu:~/git-example$ git status
Sample Output:
Step-2: Backup your branch
This is an optional step and we are doing this just to have a failsafe in case something goes wrong and we don't want to loose our files.
deepak@ubuntu:~/git-example$ git branch backup-dev
deepak@ubuntu:~/git-example$ git branch
backup-dev
* dev
main
Step-3: Reset your local repository
Next we will reset the HEAD of our local repository to point at the HEAD of latest change from alisha. This step will delete all the untracked changes from your local repository:
deepak@ubuntu:~/git-example$ git reset --hard origin/dev
HEAD is now at 4da8c06 Two
Check the commit history:
deepak@ubuntu:~/git-example$ git log --oneline
Sample Output:
As expected, now we can see the change from alisha
in the commit history. The git reset command has also cleaned up our local repository:
deepak@ubuntu:~/git-example$ git status
On branch dev
Step-4: Perform git pull
This step is actually not required, but just to be sure if this command works now:
deepak@ubuntu:~/git-example$ git pull origin dev
From gitlab.com:golinuxcloud/git-example
* branch dev -> FETCH_HEAD
Already up to date.
So we get a message that our local repo is already up to date with remote repository. This means that our git pull force has worked and we have successfully overwritten our local repo changes.
Step-5: Delete backup branch
Now that the pull operation is working properly. We don't need the backup branch which we created earlier and can be deleted:
deepak@ubuntu:~/git-example$ git branch -d backup-dev
Deleted branch backup-dev (was d7b6c56).
Example-2: git force pull to overwrite committed changes from local repository
In this section we will demonstrate a scenario when the operator wants to overwrite his or his committed changes from the local repository and perform git pull force:
Lab Environment
Here is a brief information about how our lab environment is setup. User alisha
has push changes as part of 84ae032
commit ID:
alisha@ubuntu:~/git-example$ git log --oneline
Sample Output:
While user deepak
has the following commit history:
deepak@ubuntu:~/git-example$ git log --oneline
Sample Output:
User deepak
has also committed some changes into file1 which he is planning to push to remote repo:
deepak@ubuntu:~/git-example$ git commit -m "Deepak-Three" -a [dev 414886c] Deepak-Three 1 file changed, 1 insertion(+) deepak@ubuntu:~/git-example$ git status On branch dev nothing to commit, working tree clean
But before doing a push, he plans to pull the remote repository changes:
deepak@ubuntu:~/git-example$ git pull origin dev
remote: Enumerating objects: 5, done.
remote: Counting objects: 100% (5/5), done.
remote: Compressing objects: 100% (2/2), done.
remote: Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
Unpacking objects: 100% (3/3), 261 bytes | 261.00 KiB/s, done.
From gitlab.com:golinuxcloud/git-example
* branch dev -> FETCH_HEAD
4da8c06..84ae032 dev -> origin/dev
Auto-merging file1
CONFLICT (content): Merge conflict in file1
Automatic merge failed; fix conflicts and then commit the result.
The git pull operation has failed, as alisha
has also modified the same file so we see a merge conflict.
You can get more details about the merge conflict from file1 (source file):
deepak@ubuntu:~/git-example$ cat file1 Deepak-1 Alisha-1 <<<<<<< HEAD Deepak-2 ======= Alisha-2 >>>>>>> 84ae032de0f2beee576b5490034e92a4096912c6
Follow the below steps to overcome this situation by overwriting the files from local repository.
Step-1: Perform fetch operation
We will repeat the same steps as used in Scenario-1. We know that fetch operation will only fetch the remote refs and tags but it will not merge them. Although this step can be ignored because we already attempted git pull in the previous section which has also performed git fetch.
deepak@ubuntu:~/git-example$ git fetch origin dev
From gitlab.com:golinuxcloud/git-example
* branch dev -> FETCH_HEAD
Since the branch changes were already fetched, so we get a blank output.
Step-2: Backup your active branch
This is again optional but recommended. Backup your branch as a failsafe to avoid any unforeseen situations.
deepak@ubuntu:~/git-example$ git branch backup-dev deepak@ubuntu:~/git-example$ git branch
Sample Output:
Step-3: Reset your local repository
Next we will reset our local repository to overwrite any commited or untracked changes and perform git pull force:
deepak@ubuntu:~/git-example$ git reset --hard origin/dev
HEAD is now at 84ae032 Three
The reset operation was successful. Verify the commit history:
deepak@ubuntu:~/git-example$ git log --oneline
Sample Output:
You can also check file1 content to make sure it doesn't contain any merge conflict related data:
deepak@ubuntu:~/git-example$ cat file1 Deepak-1 Alisha-1 Alisha-2
Step-4: Perform git pull
This step is optional, just to be sure that our previous steps were successful.
deepak@ubuntu:~/git-example$ git pull origin dev
From gitlab.com:golinuxcloud/git-example
* branch dev -> FETCH_HEAD
Already up to date.
Since we have already fetched everything, so nothing more to pull from remote repo.
Step-5: Delete backup branch
Once the git pull force operation is successful, we can safely delete the backup-dev branch:
deepak@ubuntu:~/git-example$ git branch -d backup-dev
error: The branch 'backup-dev' is not fully merged.
If you are sure you want to delete it, run 'git branch -D backup-dev'.
As you can see, we get an error while deleting the backup-dev branch. If you recall, we had some uncommitted changes when we had backed up our branch so we are getting this warning.
Anyhow we don't want to keep those changes so we will forcefully delete the backup branch:
deepak@ubuntu:~/git-example$ git branch -D backup-dev deepak@ubuntu:~/git-example$ git branch
Sample Output:
Example-3: Save untracked changes and perform git force pull
In this scenario we will save untracked changes from local repository and then perform git pull force.
Alisha
has committed some changes into file1
using 5328aa8
commit ID and pushed to remote repo. On the other side, user deepak
is also working on the same file in his branch.
But once he tries to pull the remote repo changes, he gets below error:
deepak@ubuntu:~/git-example$ git pull origin dev
error: cannot pull with rebase: You have unstaged changes.
error: please commit or stash them.
This is because he has some untracked changes in his local repository:
deepak@ubuntu:~/git-example$ git status
On branch dev
Changes not staged for commit:
(use "git add ..." to update what will be committed)
(use "git restore ..." to discard changes in working directory)
modified: file2
To make sure the changes from this file is not overwritten, he decides to save it using git stash:
deepak@ubuntu:~/git-example$ git stash
Saved working directory and index state WIP on dev: 5328aa8 Six
Check the list of stashed changes:
deepak@ubuntu:~/git-example$ git stash list
stash@{0}: WIP on dev: 5328aa8 Six
Now deepak
can easily perform git pull operation:
deepak@ubuntu:~/git-example$ git pull origin dev
remote: Enumerating objects: 5, done.
remote: Counting objects: 100% (5/5), done.
remote: Compressing objects: 100% (3/3), done.
remote: Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
Unpacking objects: 100% (3/3), 270 bytes | 270.00 KiB/s, done.
From gitlab.com:golinuxcloud/git-example
* branch dev -> FETCH_HEAD
4a708ca..5328aa8 dev -> origin/dev
Updating 4a708ca..5328aa8
Fast-forward
file1 | 1 +
1 file changed, 1 insertion(+)
Once git pull is successful, deepak
can pop the stashed changes and then start working on them again:
deepak@ubuntu:~/git-example$ git stash pop
On branch dev
Changes to be committed:
(use "git restore --staged ..." to unstage)
new file: file2
Dropped refs/stash@{0} (b93e4ce5c347a5bddb761be6d62e17b01e486584)
git pull vs git pull force
Git pull | git pull force |
---|---|
When creates a merge conflict | Behaves same way as git pull by creating a merge conflict |
Doesn’t run with untracked file in the local repository | Can run if implemented using git reset hard |
You have to track the local commits first before running a success pull | You can overwrite untracked commits and update the remote commit to local |
Doesn’t require stashing to secure local untracked changes | Requires git stash to secure the untracked local commits from being discarded after the pull force completion |
Summary
To sum up, you will discover that git doesn’t have a git pull force
command apart from the default git pull command. To facilitate git pull force you have to combine several other git functions with include git fetch, git reset hard and git stash. A git pull force process is simply a modification of the git fetch function.
Further Reading