forked from larics/git-tutorial-intro
-
Notifications
You must be signed in to change notification settings - Fork 0
/
collaboration.tex
274 lines (209 loc) · 8.97 KB
/
collaboration.tex
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
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
\section{Collaborating with others}
% -----------------------------------------------------------------------------
\begin{frame}[fragile]
\frametitle{Getting changes from the remote repository}
Getting remote changes is a two-step process:
\begin{enumerate}
\item \texttt{fetch} the changes from the remote repository
\begin{minted}{console}
> git fetch
> git status
> git diff <your branch> origin/<other branch>
\end{minted}
\item \texttt{merge} the changes into your local branch
\begin{minted}{console}
> git merge origin/<branch>
\end{minted}
\end{enumerate}
\begin{block}{Understanding \texttt{diff}}
\texttt{git diff a b} shows changes that need to be applied to \texttt{a} to make it the same as \texttt{b}. \texttt{a} and \texttt{b} are references to any two commits.
\end{block}
\end{frame}
% -----------------------------------------------------------------------------
\begin{frame}[fragile]
\frametitle{Syncing your code: merging}
\begin{itemize}
\item When you call \texttt{merge}, git adds a special commit known as a \textit{merge commit} to your local branch
\item The merge commit has two parent commits: your local previous head commit, and the other side's commit.
\end{itemize}
\begin{block}{\texttt{fetch}+\texttt{merge}=\texttt{pull}?}
\begin{itemize}
\small
\item \texttt{pull} will do \texttt{fetch} and \texttt{merge} in a single step
\item If the remote version has changed, and you have made local commits before pulling the remote changes, you might get yourself into trouble.\footnote{A really nice article advocating the use of \texttt{fetch}+\texttt{merge} can be found on \href{http://longair.net/blog/2009/04/16/git-fetch-and-merge/}{Mark's Blog}}
\item When you are getting back to work on a branch that you share with someone else, always \texttt{fetch}first to avoid unpleasant surprises.
\end{itemize}
\end{block}
\end{frame}
% -----------------------------------------------------------------------------
\begin{frame}[fragile]
\frametitle{Merge conflicts}
\begin{block}{Task O [Slavko]}
\begin{itemize}
\item Merge the remote changes
\item Resolve the conflicts (if any)
\item Push your changes
\item (After Mirko completes his task) Fetch the new \texttt{master}
\end{itemize}
\end{block}
\begin{block}{Task P [Mirko]}
\begin{itemize}
\item Fetch Slavko's changes
\item Merge Slavko's changes into your branch
\item Use \texttt{gitg} to examine what happened
\end{itemize}
\end{block}
\end{frame}
% -----------------------------------------------------------------------------
\begin{frame}[fragile]
\frametitle{Resolving merge conflicts}
After merging, some files might end up in a conflicted state:
\begin{minted}{console}
> git merge origin/<branch>
> git status
> git gui
\end{minted}
Conflict markers inside the file:
\begin{minted}{diff}
<<<<<<< HEAD
Code from the checked out branch ("local" in git gui)
=======
Code from the other branch ("remote" in git gui)
>>>>>>> origin/<branch name>
\end{minted}
To resolve the conflict, manually edit the file, mark resolution with \texttt{git add}, commit and push:
\begin{minted}{console}
> git add <file name>
> git commit -m "<commit message>"
> git push origin <branch>
\end{minted}
\end{frame}
% -----------------------------------------------------------------------------
\begin{frame}[fragile]
\frametitle{Visualizing merges}
\begin{multicols}{2}
\begin{figure}
\includegraphics[scale=0.5]{3-way-merge-before}
\end{figure}
\begin{figure}
\includegraphics[scale=0.5]{3-way-merge-after}
\end{figure}
\end{multicols}
\end{frame}
% -----------------------------------------------------------------------------
\begin{frame}[fragile]
\frametitle{Reverting previous commits}
\begin{itemize}
\item Another benefit of splitting the work in different commits is the ability to undo them using \texttt{git revert}.
\item To revert the offending commit:
\begin{minted}{console}
> git revert <commit ID>
\end{minted}
\item Reverting generates a \textit{revert commit}, which has the exactly opposite (inverse) set of changes.
\end{itemize}
\begin{block}{Task Q [Mirko]: Mirko gets his revenge}
\begin{itemize}
\item Revert Slavko's annoying commit.
\item Use \texttt{gitg} to examine what happened
\item Merge your branch into the \texttt{master} branch
\item Push your \texttt{master} branch to \texttt{origin}
\end{itemize}
\end{block}
\end{frame}
% -----------------------------------------------------------------------------
\begin{frame}[fragile]
\frametitle{Cleaning up local branches}
Branches are a powerful and useful tool. However, to be used effectively, we must maintain them regularly. Generally, there are two types of branches
\begin{itemize}
\item Short-lived branches (for bugfixes and features)
\item Long-lived branches
\end{itemize}
After merging a short-lived branch, perform cleanup by deleting it:
\begin{minted}{console}
> git branch -d <branch name>
\end{minted}
To delete an unmerged branch, you have to use the \texttt{-D} option, but be careful with this option, as the commits it was pointing to will become difficult to reach.
\end{frame}
% -----------------------------------------------------------------------------
\begin{frame}[fragile]
\frametitle{Cleaning up remote branches}
\begin{block}{Deleting remote branches}
\begin{itemize}
\item Can be done from the Github interface;
\\ run \texttt{git fetch --prune} afterwards to clean them up in your local copy of the remote repository
\item To delete a remote branch using the command-line interface, run \texttt{git push --delete <remote> <branch\_name>}
\end{itemize}
\end{block}
\begin{block}{Task R [Mirko, Slavko]: Clean up your branches}
Delete both the local and remote branches.
\end{block}
\end{frame}
% -----------------------------------------------------------------------------
\begin{frame}[fragile]
\frametitle{Issues and pull (merge) requests 1/2}
\emph{Pull requests} are an efficient and transparent code review mechanism. GitLab calls them \emph{Merge requests}.
\begin{block}{Task S [Mirko]: Create an Issue}
Examine the demo application and create an issue through the GitHub Web UI.
\end{block}
\begin{block}{Task T [Slavko]: Merge request}
Implement the requested fix in a new branch. Commit, and do not forget to \emph{reference the issue} in the commit message. Create a Merge request.
\end{block}
\begin{block}{Task U [Mirko, Slavko]: Code review}
Perform code review, merge the MR and delete the branch.
\end{block}
\end{frame}
% -----------------------------------------------------------------------------
\begin{frame}[fragile]
\frametitle{Issues and pull (merge) requests 2/2}
\emph{Pull requests} are an efficient and transparent code review mechanism. GitLab calls them \emph{Merge requests}.
\begin{block}{Task V [Slavko]: Create an Issue}
Ask for a \texttt{square} command to be implemented for the demo shell program.
\end{block}
\begin{block}{Task W [Mirko]: Merge request}
Implement the requested feature in a new branch. Commit, and do not forget to \emph{reference the issue} in the commit message. Create a Merge request.
\end{block}
\begin{block}{Task X [Mirko, Slavko]: Code review}
Perform code review, merge the MR and delete the branch.
\end{block}
\end{frame}
% -----------------------------------------------------------------------------
%\begin{frame}[fragile]
%
%\frametitle{Working with multiple remotes}
%
%\begin{block}{Why would I need multiple remotes?}
% \begin{itemize}
% \item We can get code changes from any repository, not just our remote repository (which is automatically set up as a remote named \texttt{origin} when cloning)
% \item A typical example is getting changes from the \textit{upstream} repository, i.e., the repository that we forked.
% \end{itemize}
%\end{block}
%
%Listing and adding remotes:
%\begin{minted}{console}
%> git remote add <remote_name> git@<hostname>:<path to repo>
%> git remote -v
%\end{minted}
%
%We can now work with the new remote in the same way as with \texttt{origin} (except we can't push into it!), e.g.:
%\begin{minted}{console}
%> git fetch <remote_name>
%> git merge <remote_name>/<branch>
%\end{minted}
%
%\end{frame}
% -----------------------------------------------------------------------------
%\begin{frame}
%
%\frametitle{Merging upstream changes}
%
%\begin{block}{Task: Merge upstream changes}
% \begin{itemize}
% \item Set up a remote called \texttt{upstream} pointing to \href{https://github.com/larics/git-tutorial-code.git}{the original repository you forked}
% \item \texttt{fetch} the \texttt{upstream} repository and compare its \texttt{master} branch with your \texttt{master} branch.
% \item Optional: for experimenting how the upstream changes will play with your changes, create a new branch.
% \item Merge the upstream \texttt{master} branch into your \texttt{master} branch (or first into your experimental branch, and then merge your experimental branch into your \texttt{master}).
% \end{itemize}
%\end{block}
%
%\end{frame}
% -----------------------------------------------------------------------------