-
Notifications
You must be signed in to change notification settings - Fork 1
/
git_conflicts.qmd
147 lines (81 loc) · 6.03 KB
/
git_conflicts.qmd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
---
title: "Managing git merge conflicts"
---
### First and foremost
**You did nothing wrong!!** Git is simply asking for your help to merge files because it can not figure it out on its own.
::: {.callout-note}
## One thing to note before we continue
`git pull` = `git fetch` (getting things from GitHub) + `git merge` (merging the versions between your local and GitHub)
:::
A conflict arises when git can not automatically merge two versions of a file. When the changes are on different files or on the same file but far apart, git will figure it out on his own and do the merge automatically. However, if changes are overlapping, git will call you to the rescue because it is not sure which version should be kept. When you are in this situation, you are "stalled" between the `git fetch` & the `git merge` and you need to edit the file(s) where there is a conflict. Luckily, git will flag the lines that have different versions for you to look at.
### A few tips to deal with merge conflicts
#### 1. If you **were not expecting** a conflict or want to roll back to your status before the conflict arise
```bash
git merge --abort
```
This does not resolve the conflict but it lets you look more into why you are having a conflict while keeping your local copy of the repository usable.
#### 2. If you **know for sure** what file version you want to keep
- keep the remote file: ```git checkout --theirs conflicted_file.txt```
- keep the local file: ```git checkout --ours conflicted_file.txt```
::: {.callout-important}
=> You still have to use `git add` and `git commit` after this to commit your changes to the git history
:::
#### 3. If you **do not know** which version to keep
Dig into the files, looking for:
```bash
<<<<<<< HEAD
local version (ours)
=======
remote version (theirs)
>>>>>>> [remote version (commit#)]
```
Manually edit the file deleting and modifying your script as needed (including all the symbols git added to flag the conflict). Save the script/file when you are done editing.
::: {.callout-important}
=> You still have to use `git add` and `git commit` after this to commit your changes to the git history
:::
Even after modifying the files, you can still abort a merge, for example you realized you kept the wrong version.
```bash
git merge --abort
```
If you realize you made a mistake once the merge is resolved, you can always run to go back to the previous commit:
```bash
git reset --hard
```
## How to minimize the risk of conflicts?
1. **Communicate**!! Who is working on what script/file today? GitHub issues and tagging people is a great way to do this
2. `commit`, `pull`, and `push` **often** , so the changes between versions are kept minimal
These two tips should help you on your git conflict free journey!!
_If conflicts keep happening in your collaboration, using `git branches` might be the next step to consider for your team._
## Example using RStudio
Ok, let's create a conflict with our favorite desserts repository.
User 1 is going to change a line on the README an push the change to GitHub.
![](img/git_conflict-01_user1_change.png){fig-align="center" width=60%}
Now user 2, is going to also make an edit to the README on this same line while **forgetting** to pull before starting to edit the file
In this example, we will be changing the favorite dessert of the same person:
![](img/git_conflict-02_user2_change.png){fig-align="center" width=70%}
Save and commit your changes.
Now it is time to pull and push your changes... however git is unsure how to reconcile the two versions of the README.md
![](img/git_conflict-04_merge_conflict.png){fig-align="center" width=90%}
::: {.callout-note}
Before this you might first have the pop-up below on your screen that prompts you to tell git what techniques it should use to resolve conflicts
![](img/git_conflict-03_merge_settings.png){fig-align="center" width=90%}
We recommend to choose the `merge` option by copy-pasting this line in the terminal:
```bash
git config pull.rebase false
```
:::
Note the tags that git has automatically inserted in the text to highlight: 1. where is the conflict and 2. what are the two versions you are trying to reconcile. Note also that RStudio is flagging the file with an orange U logo to let you know that the files are *U*nmerged.
![](img/git_conflict-05_rstudio_conflict.png){fig-align="center" width=50%}
You can edit the README to resolve the conflict to your liking. You could opt to choose one of the version
![](img/git_conflict-06_fixing conflict_oneside.png){fig-align="center" width=60%}
or to come up with a "blended" version:
![](img/git_conflict-07_fixing_conflict_compromise.png){fig-align="center" width=60%}
Once you are satisfied with your version, you can save the file and commit your changes
![](img/git_conflict-08_commit_fix.png){fig-align="center" width=60%}
Don't forget to pull and push to synchronize your local changes with GitHub.
If you now look at the history, you can see how git has tracked the conflict resolution. We will talk about branches later on, but spoiler alert it looks very much how you would merge a branch back to the main branch.
![](img/git_conflict-09_post_merge_history.png){fig-align="center" width=80%}
### Tips to reduce conflicts
1. Always start your working sessions with a pull and Commit often in small chunks
2. This can be often **avoided by good communication about who is working on various sections of each file, and trying to avoid overlaps**. But sometimes it happens, and *git* is there to warn you about potential problems. And git will not allow you to overwrite one person's changes to a file with another's changes to the same file if they were based on the same version.
3. Encapsulate your work using branches and forks. This allows you to work on your modifications without interfering with your collaborator's work until you decide it is time to merge your changes via a Pull Request. Note this can still create conflicts between versions but at least you are in control of when it will happen and the Pull Request is a great opportunity to discuss conflicts with your collaborators.