git-workshop/README.md
README.mdRaw
1# git-workshop
2*2022-05-12, done while I was at [Aragon ZK Research](https://research.aragon.org/) group.*
3
4## Table of contents
5
6- [1. Main idea](#1-Main-idea)
7- [2. Useful commands](#2-Useful-commands)
8 - [2.1. Your local config](#21-Your-local-config)
9 - [2.2. Creating branches](#22-Creating-branches)
10 - [2.3. Committing](#23-Committing)
11 - [2.4. Seeing the git history](#24-Seeing-the-git-history)
12 - [2.5. Pushing to the remote repository](#25-Pushing-to-the-remote-repository)
13 - [2.6. Amending commits or how to modify the history](#26-Amending-commits-or-how-to-modify-the-history)
14 - [2.7. Rebase and Squash](#27-Rebase-and-Squash)
15 - [2.8. Cherry pick](#28-Cherry-pick)
16 - [2.9. Rebase branch](#29-Rebase-branch)
17- [3. Examples](#3-Examples)
18 - [3.1. research-blog branches](#31-research-blog-branches)
19 - [3.2. An example of a flow using a branch](#32-An-example-of-a-flow-using-a-branch)
20- [4. Useful terminal tools](#4-Useful-terminal-tools)
21- [5. Useful resources](#5-Useful-resources)
22- [Acknowledgements](#Acknowledgements)
23
24
25
26## 1. Main idea
27Git is a **distributed version control system**, which is used for collaborative code editing to keep track of code changes.
28Git is not the same than Github, Github is a remote repository that uses Git.
29
30<img src="imgs/git-branches-draw.png" style="width:50%;" />
31
32*(src of the diagram: https://nvie.com/posts/a-successful-git-branching-model/ )*
33
34
35## 2. Useful commands
36Along this section, might be useful to try to reproduce the operations showcased in this tool: https://git-school.github.io/visualizing-git/
37
38### 2.1. Your local config
39It's important to tell to git who are you: in `.gitconfig` file:
40```
41[user]
42 email = your@email.com
43 name = yourname
44```
45
46Alternatively, you can also configure it directly from the command line:
47```
48git config --global user.email "your@email.com"
49git config --global user.name "yourname"
50```
51
52Now, you can print your config to confirm that everything is fine:
53```
54git config --global -l
55```
56
57Take in mind, that in Github, it only shows your commits authorship in which the author's email matches your Github configured email.
58
59
60### 2.2. Creating branches
61For repositories where there is more than one person working, it's a good practice to use branches. In this way, the other people can review the changes from the branch before moving them to the `main`/`master` branch.
62
63To create a new branch:
64
65```python
66# first ensure that we have the last remote changes of the main branch:
67git checkout main
68git pull origin main
69
70# we proceed with the branch creation:
71git branch yourbranchname
72```
73Now this new branch `yourbranchname` is a pointer to the last commit, which is also pointed by the `main` branch. If we now add a new commit to the `yourbranchname` branch, it will diverge from the `main` branch.
74
75(Also you can use `git checkout -b yourbranchname`, which will create the new branch and move to it)
76
77<img src="imgs/git-diagram-0.png" style="width:50%;" />
78
79Usually, the name of the branch tries to reflect what you're adding in that branch (eg. if you're adding an introductory article on lattice cryptography, the branch can be named `intro-lattice-cryptography`).
80If you're fixing something, it's a common practice to specify it in the branch name (eg. `fix/typo-lattice-article`).
81
82If you want to move to an already existing branch, you can use:
83```
84git checkout the_already_existing_branch_name
85```
86
87### 2.3. Committing
88We assume that we edited some files and we want to commit the changes, we'll use:
89```python
90# first let's check which files have changes:
91git status
92
93# to add the edited files:
94git add .
95
96# we can run again the 'status' command, to see that we added the edited files:
97git status
98
99# we're ready to commit the changes:
100git commit -m "this is the commit message"
101```
102
103**Important**: The commit message should describe the changes that we are adding in the commit, so later when revisiting the git history logs, another person can get the context on what has been modifyied in each commit.
104
105**Note 1**: the commit message can have multiple lines, the first line should not be longer than 50 characters.
106To do a new commit with multiple lines, you can just use `git commit`, and your configured text editor will open to edit the commit message.
107**Note 2**: notice that we committed the changes to our local version of the repository. The remote repository (eg. in Github) does not have our last commit yet.
108
109### 2.4. Seeing the git history
110```
111git log
112```
113
114For other visualization useful tooling, check the [Useful terminal tools](#4-Useful-terminal-tools) section.
115
116### 2.5. Pushing to the remote repository
117We have committed some changes to our branch, and we want to push those changes to the remote repository (eg. hosted in Github).
118
119In order to push to the remote branch:
120```
121git push origin yourbranchname
122```
123
124And now, from the Github web we can open a PullRequest (usually named 'PR').
125
126### 2.6. Amending commits or how to modify the history
127Imagine that we did a commit, but we want to 'edit' it. We can edit it with the 'amend' command:
128```python
129# once the files are edited, let's track the changes:
130git add .
131
132# now instead of creating a new commit, we amend the last one:
133git commit --amend
134# here the text editor will be triggered, so we can edit the commit message
135```
136
137If the old commit was already pushed to the remote repository (eg. Github), now our local commit looks different from the equivalent remote one (and their hashes will differ). If we are in a un-protected branch, we can force the push, which means that despite the remote repository already has the equivalent commit, we will overwrite it with our amended commit:
138```
139git push origin yourbranchname --force
140```
141Be aware, that with `--force` you're overwriting the remote commit, so is a flag that should be used with extreme care, as we could delete relevant code.
142
143
144### 2.7. Rebase and Squash
145Imagine that you have a git history that looks like:
146```
147commit 2547306f0bc9199f34ada8e72b706968752e94eb (HEAD -> yourbranchname, origin/yourbranchname)
148Author: username <username@email.com>
149Date: Mon May 9 15:17:19 2022 +0200
150
151 Fix typo on the description
152
153commit a2ab24314c86b7f8a6a980aa3b57dd5fe339b14e
154Author: username <username@email.com>
155Date: Mon May 9 13:32:40 2022 +0200
156
157 Update intro-lattice-cryptography.md
158
159commit 31aea34e1ab381ae14f5a97e189da12510896536
160Author: username <username@email.com>
161Date: Mon May 9 13:21:01 2022 +0200
162
163 Update intro-lattice-cryptography.md
164
165commit 2ca12c978966943f8400eccdc3f7703f78f77fed
166Author: username <username@email.com>
167Date: Mon May 9 13:13:23 2022 +0200
168
169 Add intro-lattice-cryptography.md
170
171commit f9068940b8cb96647f306ba094b7931031b8b4fb (origin/main, origin/HEAD, main)
172Author: username <username@email.com>
173Date: Mon May 9 13:09:53 2022 +0200
174
175 Update css style
176```
177
178Assume that the last 4 commits are updates to the same file (`intro-lattice-cryptography.md`). In order to keep a more clean git history, we may want to combine all those 4 commits into a single one. We can do it with:
179
180```
181git rebase -i f9068940b8cb96647f306ba094b7931031b8b4fb
182```
183
184Notice that `f9068940b8cb96647f306ba094b7931031b8b4fb` is the hash of the commit previous to the one until where we want to edit the commits.
185
186Now we will be displayed with the text editor showing the following:
187```
188pick 2ca12c9 Add intro-lattice-cryptography.md
189pick 31aea34 Update intro-lattice-cryptography.md
190pick a2ab243 Update intro-lattice-cryptography.md
191pick 2547306 Fix typo on the description
192```
193
194We now can edit it changing the `pick` by `squash`/`s` at those commits that we want to squash with the previous one:
195```
196pick 2ca12c9 Add intro-lattice-cryptography.md
197s 31aea34 Update intro-lattice-cryptography.md
198s a2ab243 Update intro-lattice-cryptography.md
199s 2547306 Fix typo on the description
200```
201
202With this, what we are doing is 'squashing' the 3 last commits into the first one (`2ca12c9`).
203
204Now, if we run `git log`, we will see:
205```
206commit 6760e0c7bd05602de0483126ae51e9d6f63b4587 (HEAD -> yourbranchname, origin/yourbranchname)
207Author: username <username@email.com>
208Date: Mon May 9 15:20:19 2022 +0200
209
210 Add intro-lattice-cryptography.md (our squashed commit which includes all the 3 other commits)
211
212commit f9068940b8cb96647f306ba094b7931031b8b4fb (origin/main, origin/HEAD, main)
213Author: username <username@email.com>
214Date: Mon May 9 13:09:53 2022 +0200
215
216 Update css style
217```
218
219### 2.8. Cherry pick
220Cherry pick allows you to get a copy of specific commits from another branch to your branch.
221
222Imagine that there is a bug in production, and is solved in a branch where we are also introducing other changes, but we don't want to move those changes yet into production. So, we want to 'cherry pick' from the branch the specific commit that fixes the bug, but without getting the rest of commits of that branch which introduces other features.
223
224We can do this by:
225```
226git cherry-pick commithash
227# where 'commithash' is the hash of the commit that we want to copy to our branch
228```
229
230### 2.9. Rebase branch
231Imagine that we have started our branch two days ago, but during these last two days, the `main` branch has advanced and now has new commits that we don't have in our branch. We can "rebase" our branch to last `main` changes, and in this way, it would be like we started our branch after those last commits from `main`. (be careful, if the `main` branch last commits touch the same file lines than your branch, you could have "git conflicts")
232
233Rebasing a branch to last `main` commits:
234```
235# first we go to the main branch:
236git checkout main
237
238# now we pull the last changes from the remote repository:
239git pull origin main
240
241# now we go back to our branch:
242git checkout yourbranchname
243
244# now we want to rebase our branch to last main version:
245git rebase main
246```
247
248
249## 3. Examples
250
251### 3.1. research-blog branches
252Screenshot taken from [network graph of research-blog](https://github.com/aragon/research-blog/network) repository:
253
254<img src="imgs/git-screenshot.png" style="width:50%;" />
255
256### 3.2. An example of a flow using a branch
257The following steps, will lead to the following diagram of branches:
258```python
259git commit -m "Commit A"
260git branch new-sig-scheme
261git commit -m "Commit B"
262git commit -m "Commit C"
263git checkout new-sig-scheme
264git commit -m "Add new hash"
265git commit -m "Add sig generate"
266git commit -m "Sig verif"
267git checkout master
268git merge new-sig-scheme
269git commit -m "Use new sig"
270```
271
272<img src="imgs/git-diagram-1.png" style="width:50%;" />
273
274*(take in mind that the graph starts to left and goes to right, the arrows point backwards to represent that a commit has a pointer to the previous one)*
275
276You can try to recreate this flow step by step in: https://git-school.github.io/visualizing-git/ .
277
278## 4. Useful terminal tools
279- [tig](https://jonas.github.io/tig/INSTALL.html): visit the diffs from the git history.
280- [delta](https://github.com/dandavison/delta): git diff syntax highlighting tool (highly customizable).
281- `gitg`: useful to print an overview of the git history with a small diagram of the branches. To use it, add to your `.bashrc`/`.zshrc` file:
282 ```
283 alias gitg="git log --color --graph --abbrev-commit --pretty=format:'%Cred%h%Creset%C(yellow)%d%Creset %s %Cgreen(%ar)%C(cyan) %an<%ae>%Creset'"
284 ```
285- `git wip`: useful to print the last branches that you worked on locally.
286 - in your `.gitconfig` file, you can add the following lines to add the `git wip` command:
287 ```
288 [alias]
289 wip = for-each-ref --sort='authordate:iso8601' --format=' %(color:green)%(authordate:relative)%09%(color:white)%(refname:short)' refs/heads
290 ```
291
292
293## 5. Useful resources
294This document contains just an overview of some of the useful commands available in git, but is worth to spend some time reading the git docs or doing a tutorial on it.
295
296- Git tutorial: https://www.w3schools.com/git/git_intro.asp
297- Git visualizing tool: https://git-school.github.io/visualizing-git/ . This resource is useful to play a bit while visualizing how the commits and branches look like.
298- Git docs: https://git-scm.com/doc
299
300## Acknowledgements
301Many thanks to Edu ([@ed255](https://github.com/ed255)) who showed me some of the git commands and tools that appear in this document.