You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: understanding-git.tex
+78-5Lines changed: 78 additions & 5 deletions
Original file line number
Diff line number
Diff line change
@@ -99,6 +99,14 @@ \section{Introduction}
99
99
\begin{frame}
100
100
\frametitle{Reading Git graphs}
101
101
Git repositories are often represented using a directed acyclic graph (DAG).
102
+
\note{
103
+
\textbf{Directed:} The graph edges are one-way.\\
104
+
\textbf{Acyclic:} There is no way to return to a node once you have passed it.\\
105
+
\textbf{Graph:} A mathematical model with nodes and edges that connect nodes.
106
+
107
+
A DAG forms a tree structure, and you can refer to a connected Git DAG as a tree.\\
108
+
}
109
+
102
110
\begin{figure}
103
111
\centering
104
112
\begin{tikzpicture}
@@ -123,12 +131,16 @@ \section{Introduction}
123
131
\vfill
124
132
\begin{block}{Arrows}
125
133
The arrows point to the commit's parent(s), not the flow of time.
134
+
\note{Think of the arrows as representing a ``depends on'' relationship.}
126
135
\end{block}
127
136
\end{frame}
128
137
129
138
\begin{frame}
130
139
\frametitle{Our reference repository}
131
140
\defaultrepo
141
+
\note[item]{The initial commit is \grefspec{A}.}
142
+
\note[item]{There are two branches, \gbranch{master} and \gbranch{topic}.}
143
+
\note[item]{Commit \grefspec{D} was made after \gbranch{topic} split from the mainline.}
132
144
\end{frame}
133
145
134
146
\begin{frame}
@@ -149,8 +161,13 @@ \subsection{Introduction}
149
161
\item Commits record the changes of a repository.
150
162
\item Commits also include a message, a timestamp (usually of creation), and an author.
151
163
\item Except for the first commit, commits reference one or more parent commits.
164
+
\note[item]{More precisely, root commits have no parent. The first commit is a root commit, but a repo can have multiple root commits.}
152
165
\item Commits are identified by a SHA-1 hash. This hash can be abbreviated to its unique prefix (usually 7).
166
+
\note[item]{The minimum abbreviated hash length is 4 characters.}
167
+
\note[item]{Commits are effectively read-only because changing any of the properties of a commit changes its hash.}
168
+
\note[item]{Linux Torvalds on SHA-1 collisions: \url{https://marc.info/?l=git&m=148787047422954}}
153
169
\item The bulk of the Git model is the DAG of commits.
170
+
\note[item]{The rest of the Git model is the plumbing and the Git file system. This is highly out of scope for this presentation.}
154
171
\end{itemize}
155
172
\end{frame}
156
173
@@ -315,6 +332,12 @@ \subsection{\gitcmd{commit}}
315
332
316
333
After entering a commit message in the editor, commit \grefspec{F} is added containing the staged changes.
317
334
\gHEAD{} and \gbranch{topic} are advanced to \grefspec{F}.
335
+
336
+
\note{
337
+
The commit message can be entered on the command line using the \gflag{-m} (\gflag{--message}) flag, with multiple \gflag{-m} flags being combined as multiple paragraphs.
338
+
Using this flag may create bad commit message habits, so consider using \gflag{-m} to start your message
339
+
and additionally pass the \gflag{-e} (\gflag{--edit}) flag to bring up the editor to continue editing your message.
A new commit, \grefspec{D$'$}, that contains the same changes as \grefspec{D} was added on top of \grefspec{E}. \gHEAD{} and \gbranch{topic} were advanced to \grefspec{D$'$}.
381
+
382
+
\note{
383
+
This is a bad example because it would be better to do a \gitsubcmd{rebase} or a \gitsubcmd{merge} in this case,
\item Directly checking out a commit or tag results in a ``detached \gHEAD{}''.
634
+
\note[item]{A detached \gHEAD{} results in any situation where the ref that is checked out cannot normally be updated. Tags cannot be updated by issuing a \gitcmd{commit}, for example, so checking out a tag results in a detached \gHEAD{}.}
595
635
\item Commits from this commit may be made, but they will be lost unless a branch or tag is made.
596
636
\end{itemize}
597
637
\vfill
598
638
\begin{block}{Unreachable and dangling commits}
599
639
Unreachable commits are commits that are not referenced by a branch or tag. Dangling commits are unreachable commits that aren't referenced by another commit. Unreachable commits may be checked out using their SHA-1 hash until they are garbage collected.
640
+
\note[item]{By default, garbage collection usually removes unneeded objects after two weeks. See the man page for \gitcmd{gc} for details.}
600
641
\end{block}
601
642
\end{frame}
602
643
@@ -762,8 +803,10 @@ \subsection{\gitcmd{rebase}}
762
803
\vfill
763
804
\begin{block}{Rebasing shared public branches}
764
805
Don't rebase branches that others are working on or have branched off from, especially \gbranch{master}. Complications arise downstream when such a rebase is performed, and it is generally considered rude to rewrite public history.
765
-
%%% man git-rebase
806
+
807
+
\note[item]{The \texttt{git-rebase(1)} man page has a section on recovering from an upstream rebase.}
766
808
\end{block}
809
+
\note[item]{\gitcmd{rebase} can do a lot more than reapplying commits to another base, including editing and reordering commits. More details can be found in the man page.}
767
810
\end{frame}
768
811
769
812
\begin{frame}
@@ -797,6 +840,11 @@ \subsection{\gitcmd{rebase}}
797
840
\end{figure}
798
841
799
842
New commits \grefspec{C$'$} and \grefspec{E$'$} with the same changes as \grefspec{C} and \grefspec{E} respectively were applied onto the tip of \gbranch{master} (\grefspec{D}). Commits \grefspec{C} and \grefspec{E} have become unreachable.
843
+
844
+
\note{
845
+
Git visualizations will show branches where one is a direct ancestor of the other in a straight line like this.
846
+
This kind of presentation reinforces two facts: 1) \gbranch{master} is not special to Git, and 2) branches are just labels.
847
+
}
800
848
\end{frame}
801
849
802
850
\begin{frame}
@@ -807,7 +855,8 @@ \subsection{\gitcmd{rebase}}
807
855
\item Perform a \gitsubcmd{reset --hard} to the target branch. This is the ``unwinding'' step.
808
856
\item\gitsubcmd{cherry-pick} each commit one by one from the fork point to the former tip of the branch, excluding merge commits.
Creating a temporary branch before the rebase prevents the original commits from becoming unreachable, meaning that restoring the original branch is as simple as doing a \gitsubcmd{reset} to the temporary branch.
989
+
990
+
\note{
991
+
\gitcmd{reflog} makes this trick unnecessary (unless you need to prevent the old commits from being garbage collected),
\item Will fail if the remote branch is not an ancestor of the local branch unless \gflag{--force} (\gflag{-f}) is used.
1474
+
\note[item]{The behaviour of \gitcmd{push} can be configured using the \texttt{push.default} option in the configuration file.}
1408
1475
\item Tags must be pushed separately with the \gflag{--tags} flag.
1476
+
\note[item]{It is not entirely true that tags must be pushed separately. Tags can be specified as arguments along with branches and they will be pushed.}
1409
1477
\end{itemize}
1410
1478
\vfill
1411
1479
\begin{block}{\gflag{--force-with-lease}}
1412
1480
The \gflag{--force} flag is dangerous and should not be used lightly because it can cause another person's work to be lost.
1413
1481
The \gflag{--force-with-lease} flag is safer since it will only force-push if the tracking branch points to the same commit as on the remote repo.
1482
+
\note[item]{To make it easier to specify \gflag{--force-with-lease}, you can make an alias.}
1414
1483
\end{block}
1415
1484
\end{frame}
1416
1485
@@ -1583,6 +1652,10 @@ \subsection{\gitcmd{push}}
1583
1652
\end{figure}
1584
1653
1585
1654
Commit \grefspec{F} is lost since the remote branch reference was forcibly updated.
1655
+
\note{
1656
+
Since Git is distributed, someone else \emph{might} have a copy of commit \grefspec{F} and you can recover from there,
0 commit comments