Introduction
In our previous article on the git version control system, we explained how we could modify our files in repositories in our GitHub account and then pull the changes from GitHub to the git repositories on our local system and keep the files in synchronization. Now, what if we modified the same piece of information in a file on GitHub as well as within our local git repository? In this article, we will demonstrate how we would proceed if we modified the same information in a file on GitHub as well as locally within our git repository.
Git allows any number of parties to work on the same file at the same time independently of one another.
To demonstrate we’ll be using a Perl script named hello.pl available in my local git repository under the folder /home/sahil/perl_scripts_for_training. Given below are the contents of the script.
[sahil@linuxnix perl_scripts_for_training]$ pwd /home/sahil/perl_scripts_for_training [sahil@linuxnix perl_scripts_for_training]$ cat hello.pl #!/usr/bin/perl -w ###################################### #Author: Sahil Suri #Date: 24/03/2018 #Purpose: Hello World in Perl #version: v1.0 ###################################### print "Hello World\n"; print "Hello World again\n" [sahil@linuxnix perl_scripts_for_training]$
I’ve modified the script in my local repository such that it has the following content now:
[sahil@linuxnix perl_scripts_for_training]$ cat hello.pl #!/usr/bin/perl -w ###################################### #Author: Sahil Suri #Date: 24/03/2018 #Purpose: Hello World in Perl #version: v1.0 ###################################### print "Hello World\n"; print "Hello World again.\nI'm Sahil\n"
When we execute the script we get the following output:
[sahil@linuxnix perl_scripts_for_training]$ ./hello.pl Hello World Hello World again. I'm Sahil
Now, we’ll add this file to the staging area and commit our changes.
[sahil@linuxnix perl_scripts_for_training]$ git add hello.pl [sahil@linuxnix perl_scripts_for_training]$ git commit -m "Modified the file hello.pl" [master 0cf7bb1] Modified the file hello.pl 1 file changed, 1 insertion(+), 1 deletion(-) [sahil@linuxnix perl_scripts_for_training]$
Now let’s change the same statement in the script on GitHub. Given below is a screenshot of the original content of the file as I opened it in GitHub.
Now we’ve changed one statement and now the script has the following content:
Now we’ve modified the same content within our file at two different places. At this stage if we try to push our changes we get the below message:
[sahil@linuxnix perl_scripts_for_training]$ git push origin master To git@github.com:sahilsuri007/perl_scripts_for_training.git ! [rejected] master -> master (fetch first) error: failed to push some refs to 'git@github.com:sahilsuri007/perl_scripts_for_training.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 merge the remote changes (e.g., hint: 'git pull') before pushing again. hint: See the 'Note about fast-forwards' in 'git push --help' for details. [sahil@linuxnix perl_scripts_for_training]$
Git is helpful in the sense that it provides users with hints when a git command results in an error. It suggests to us that we should perform a git pull first to merge the changes from the remote to the local repository before attempting to execute a git push command. If we execute the git pull command in this scenario we get the following message:
[sahil@linuxnix perl_scripts_for_training]$ git pull origin master remote: Counting objects: 3, done. remote: Compressing objects: 100% (3/3), done. remote: Total 3 (delta 2), reused 0 (delta 0), pack-reused 0 Unpacking objects: 100% (3/3), done. From github.com:sahilsuri007/perl_scripts_for_training * branch master -> FETCH_HEAD Auto-merging hello.pl CONFLICT (content): Merge conflict in hello.pl Automatic merge failed; fix conflicts and then commit the result.
As we can observe from the above output git tried to run an automerge on the file but since the same line in the file had been modified at both locations git doesn’t exactly know how it should incorporate these changes. Therefore git reports a merge conflict. Git tells us that since there is a conflict the merge has failed. If we open the file in vim we will observe that git has indented the portion of the file where the merge conflicts were found. Given below is the output:
[sahil@linuxnix perl_scripts_for_training]$ vim hello.pl #!/usr/bin/perl -w ###################################### #Author: Sahil Suri #Date: 24/03/2018 #Purpose: Hello World in Perl #version: v1.0 ###################################### print "Hello World\n"; <<<<<<< HEAD print "Hello World again.\nI'm Sahil\n" ======= print "Hello World again.\nMy name is Sahil.\n" >>>>>>> 6e528de1548b471fb183c1138a27698677ea6a4a
Here the location of the conflict is separated by equal to(=) signs and the line below the word HEAD is the version of the line available in the file in our local git repository. The commit hash refers to the version of the line in the file available on GitHub.
So now we will have to manually fix the merge conflict by editing the file. I’ve edited the file in vim and the modified version of the file has the following content:
[sahil@linuxnix perl_scripts_for_training]$ cat hello.pl #!/usr/bin/perl -w ###################################### #Author: Sahil Suri #Date: 24/03/2018 #Purpose: Hello World in Perl #version: v1.0 ###################################### print "Hello World\n"; print "Hello World again.\nMy name is Sahil.\n"
If we run git status we will see that since the file has been modified we need to add it to the staging area and commit the changes.
[sahil@linuxnix perl_scripts_for_training]$ git status # On branch master # You have unmerged paths. # (fix conflicts and run "git commit") # # Unmerged paths: # (use "git add <file>..." to mark resolution) # # both modified: hello.pl # no changes added to commit (use "git add" and/or "git commit -a")
So let’s commit the file to save our changes locally.
[sahil@linuxnix perl_scripts_for_training]$ git add hello.pl [sahil@linuxnix perl_scripts_for_training]$ git commit -m 'resolved merge conflict in hello.pl' [master 913ff69] resolved merge conflict in hello.pl [sahil@linuxnix perl_scripts_for_training]$ [sahil@linuxnix perl_scripts_for_training]$ git status # On branch master nothing to commit, working directory clean [sahil@linuxnix perl_scripts_for_training]$
Now if we push our changes to the remote i.e. GitHub the git push command will execute successfully as shown below.
[sahil@linuxnix perl_scripts_for_training]$ git push origin master Counting objects: 8, done. Delta compression using up to 2 threads. Compressing objects: 100% (4/4), done. Writing objects: 100% (4/4), 513 bytes | 0 bytes/s, done. Total 4 (delta 2), reused 0 (delta 0) remote: Resolving deltas: 100% (2/2), completed with 2 local objects. To git@github.com:sahilsuri007/perl_scripts_for_training.git 6e528de..913ff69 master -> master
Conclusion
In this article, we demonstrated how we would work with a file that had been edited via multiple sources at the same location through the means of a practical example. We hope that you’ve found this article to be useful and we look forward towards your suggestions and feedback.
Sahil Suri
Latest posts by Sahil Suri (see all)
- Google Cloud basics: Activate Cloud Shell - May 19, 2021
- Create persistent swap partition on Azure Linux VM - May 18, 2021
- DNF, YUM and RPM package manager comparison - May 17, 2021
- Introduction to the aptitude package manager for Ubuntu - March 26, 2021
- zypper package management tool examples for managing packages on SUSE Linux - March 26, 2021