## GitHub Exercises
---
## What is GitHub?
Cloud-based platform for hosting git repositories
Enhances reproducibility of research:
1. Shared Version control (via Git)
2. Collaboration and transparency
3. Open source hub and free
4. Documentation and literate programming (`README.md`)
5. Automation (with GitHub Actions)
6. Exposure on job market (public profile)
---

[Source](https://medium.com/@codingworld/git-vs-github-desktop-unleashing-the-power-of-version-control-798f17057c60)
---
## Private vs public repositories
---
<!-- .slide: style="font-size: 0.68em;" -->
## Exercise: simulating work of two developers on GitHub
1. Create new folder: mkdir github-demo
2. cd github-demo
4. git init dev1
5. cd dev1
6. Change name and email of dev1: `git config --local user.name "Developer_1"` and `git config --local user.email "Developer_1"`
7. Create text file: `touch text.txt`
8. Stage and commit changes
9. Create empty GitHub "github-demo" repository
10. Run this in dev1:
11. 
---
10. Check files in your GitHub repo
11. go to your local folder github-demo: `cd ..`
12. `git clone https://github.com/Kozubowski/github-demo.git dev2` (you have to paste your own GitHub link)
13. cd dev2
14. Change name and email of dev2: `git config --local user.name "Developer_2"` and `git config --local user.email "Developer_2"`
15. In dev2 check config file in .git folder
---

[Source](https://www.geeksforgeeks.org/git/what-is-a-git-repository/)
---
## What happens when you connect to GitHub repo?
```
[remote "origin"]
url = https://github.com/user/repo.git
fetch = +refs/heads/*:refs/remotes/origin/*
```
In config git specifies how to map remote branches to local ones during fetch.
- Left: all branches on the remote
- Right: how to store them locally (remote-tracking branches)
---
<div style="transform: scale(0.55); transform-origin: top;">
## Remote branch
origin = given name for the remote repository (you can change it)
origin/branch_name locally = last commit hash fetched from the remote. It is not local branch, it is a remote-tracking branch.

</div>
---
<div style="transform: scale(0.75); transform-origin: top;">
## Can I switch to origin/branch?
Yes, but you will end up in detached HEAD state

</div>
---
## git fetch vs git pull

[Source](https://medium.com/@sabbirhossain_70520/git-fetch-vs-git-pull-691823ed4239)
---
<div style="transform: scale(0.70); transform-origin: top;">
After git fetch:

</div>
---
<div style="transform: scale(0.70); transform-origin: top;">
After git pull

git pull = git fetch + git merge
</div>
---
## git pull
git pull `<remote>` `<branch-name>`
The branch that you are on matters for git pull. Just like with git merge you will apply changes to the branch that you are currently on.
---
<!-- .slide: style="font-size: 0.85em;" -->
## Exercise: updating local repo with remote changes
```
1. cd ../dev1
2. echo "Added by dev1" > test.txt
3. git add .
4. git commit -m "Added the file by dev1"
5. git status
6. git push origin main
7. git status
# Then dev2 wants to get up to date with changes made by dev1
cd ../dev2
ls
git pull
# Check what changed:
ls
# Check commit history made by dev1:
git log
```
---
<!-- .slide: style="font-size: 0.85em;" -->
## Exercise: pulling changes before pushing
1. Create a `readme.md` file in your dev2 repository.
```
touch readme.md
```
2. Stage, commit and push the file.
```
git add .
git commit -m "Added readme.md"
git push origin main
```
3. Go to the dev2 repository.
```
cd ../dev1
```
4. Run git status
---
5. Fetch information about changes from the central repository `git fetch`. Run `git status`. What has changed?
6. Check what has changed
```
git diff main origin/main
# and see incoming commits:
git log main..origin/main
```
---
7. As a dev1 create test1.txt, stage, commit and push.
```
cd ../dev1
echo "A line added by Dev1" > test1.txt
git add .
git commit -m "Added test1"
git push origin main
```
What happens? Resolve the issue following Git hints. Try `git pull`
8. Pull new changes and check local files:
```
git config pull.rebase false
git pull
ls
git push origin main
```
---
## Exercise: merge conflict
In Exercise 6 we had a divergence, but without a conflict (commits differed, but there were no conflicting changes to files).
What if two devs make two different versions of a file?
1. In Dev2 (`cd ../dev2`), create a new file called test1.txt with the line "A line added by Dev2". Stage, commit and try to push. Follow the hints. Select git pull with merge (git config pull.rebase false) and then git pull.
---
2. There's a conflict because Dev1 committed a different test1.txt file earlier.
We're in a merging mode. We can edit the file (e.g. in VSC) to figure out what should remain. Then stage it and commit it.
The merge becomes a new commit (try git log)
Push the resolved file to GitHub (git push origin main) and check remote repo.
<!-- ---
## Exercise
1. Register at GitHub (or use an existing account).
2. Fork the course [repository](https://github.com/Kozubowski/Reproducible_Research_2026).
3. Clone your fork repository to your local computer, so you can work on it (use the option you prefer).
4. Go to the "fork-demo" folder, edit the hello.txt file inside.
5. Stage the change, commit it and push it.
-->
---
<!-- .slide: style="font-size: 0.85em;" -->
## upstream
Sets the remote branch your local branch tracks. Manages relationship between local and remote branches.
Upstream tells:
- where git pull should pull from
- where git push should push to
```
git branch --set-upstream-to=origin/main
# While pushing:
git push -u origin feature
# Because you set up upstream, next time you can just run:
git push
# Check upstream:
git branch -vv
```
---
<div style="transform: scale(0.85); transform-origin: top;">

[Source](https://devconnected.com/how-to-set-upstream-branch-on-git/)
</div>
---
<!-- .slide: style="font-size: 0.85em;" -->
## Exercise: remote branches and pull request
```
# 1. Go to dev2 repository
# 2. Create new local branch by copying remote branch
git fetch origin
git switch -c new-branch-name origin/main
# or older:
git checkout -b new-branch-name origin/main
git branch -a # or git branch -r
# 3. Add some commits
echo "A line added by Dev1" >> test1.txt
# 4. Stage, commit and push.
# 5. Try git push. What happened?
# Then:
git push -u origin new-branch-name
# Check upstream:
git branch -vv
```
---
```
# 5. Go to dev1 and fetch changes
cd ../dev1
git fetch
git status
# Show all branches (including remote)
git branch -a
# You can create local branch based on remote one:
git switch new-branch-name
# 6. Go to GitHub and initialize a pull request
```
---

[Source](https://www.linkedin.com/posts/alexxubyte_systemdesign-coding-interviewtips-activity-7424855605913415681-xWVs)
---
## Git branching game
https://learngitbranching.js.org/
{"title":"GitHub Exercises","description":"Create new folder github-demo","contributors":"[{\"id\":\"9b02b446-e66a-4b87-ad0b-21574e73f20f\",\"add\":10267,\"del\":2409,\"latestUpdatedAt\":1774351408641}]"}