This course has already ended.

Team Work in Version Control

In software development each team member works in their own local repository that contains the contents of the remote repository as a snapshot at a given time. When work is finished, and tested to work correctly, the complete code in synchronised as a part of the software by adding is to the remote repository shared by all. As long as you are working on your own code locally the work of others does no affect your work.

The changes others have made become visible when:

  1. Someone else has pushed changes from their local repository

  2. Local repository is updated from the remote repository

When multiple people are working in the same repository there is a risk for several people editing the same file (edit or remove) at the same time. This creates a conflict.

A typical conflict situation is depicted in the picture below. There two new commits D1 and D2 have been made in two separate local repositories. Both are preseded with commit C available in the remote repository. The first person to make a push won’t notice any problems. In the remote repository there is a new commit D1 and the branch is updated to point to this new commit normally. When the second person tries to perform a push problems arise.

Remote repository thinks that branch head is at commit D1 and the second users local repository thinks that the head should be at D2. Version control cannot know, which of these users has the correct version, so by default Git will prevent this operation because there is no clear solution for the problem. This might also indicate user error. Instead Git lets the user to solve this problem.


Version conflict (picture from the Git course)

In practice we have different solutions for the problem, neither of which is better than the other for sure. For example:

  1. Commits can be merged.

  2. Reject D2.

  3. Add D2 and force remote branch to point to D2 which would result in rejection of D1.

  4. Both commits can be defined as new branches.

  5. Change where D2 is pointing to.

Git cannot automagically decide the best approach to these kinds of situations.


Do not use –force if push fails

In the previous situation this would have resulted in D1 getting replaced with D2 If you don’t know what you’re doing you can:

  1. Destroy someones work.

  2. Rewrite valid version history with a corrupt one.

  3. Worst case scenario is losing the entire Git history.

None of these will be thanked for by your team mates so do not use –force.

Team work and conflicts in version control (kesto 24:11)

Fixing a simple conflict

When a conflict occurs, Git gives a clear notification of the situation. Information on the status can be received with git status which is useful anyways when following the state of the repository.

$ git status
On branch main
You have unmerged paths.
  (fix conflicts and run "git commit")
  (use "git merge --abort" to abort the merge)

Unmerged paths:
  (use "git add <file>..." to mark resolution)

both modified:   conflict.txt

Git marks the conflicting points into the file itself:

$ less conflict.txt
<<<<<<< HEAD
one opinion on input
another opinion on the same line
>>>>>>> conflicting-branch

======= marks the line between the conflicting commits: All contents between <<<<<<< HEAD and it depict the contents of the file in thw remote repository where HEAD is pointing. Similarly everything below it up to >>>>>>> conflicting-branch show the contents found in the commit being added.

The fix is done by editing the file so that no conflict markers exist. This is as such straightforward but requires communication and precision as a decision on which change remains must be made: your, theirs or possibly a combination of both. After the fic it is added under version control as a new commit:

git add conflicts.txt
git commit -m"Resolved merge conflict as discussed"
git push origin HEAD

It is important to remember that none of the team members is alone in the project the fixing the conflict is not getting your own commit through.

It is possible to completely avoid the situation by having everyone on the team working in their separate branches. Then the master branch should be in such a shape that anyone joining the team can start their own branch from master branch. When a member of the team completes and tests a feature it can be made part of master branch.

Git-demo (kesto 12:48)

Posting submission...