# Undestanding Code Managment Using Git/Gerrit Tools
https://hcp5-sources.int.esrlabs.com/Documentation/index.html
## 1. repo
1. **repo init --manifest-url <url>** command initializes repo in the current directory. That's, it downloads the latest repo source and a manifest.xml file that describes the directory structure of the git repositories, and store all of these in .repo sub-directory in the current directory.
2. **repo sync** - updates working tree to the latest revision. That's, it synchronizes local project directories with the remote repositories specified in the manifest file. If a local project does not yet exist, it will clone a new local directory from the remote repository and set up tracking branches as specified in the manifest. If the local project already exists, it will update the remote branches and rebase any new local changes on top of the new remote changes.
3. **repo start featureName --all** - This command starts a branch master for all the repositories. It is important to do it otherwise you are working on a detached head state.
4. Adding a new GIT repository to the project
```bash=
vim .repo/manifests/default.xml
git add default.xml
git commit -m "added new stuff to project"
git push origin default:master
repo sync
```
5. Check all repositories for changes since a specific date
```bash=
# make sure to use the latest repo, as -p will not work
repo forall -pc git log --since="1.11.2020" --pretty=oneline --graph
```

## 2. git


1. **Gitk** - visualize Git tree
https://hcp5-sources.int.esrlabs.com/Documentation/user-upload.html
```bash=
gitk --all
```
2. Standard workflow with existing Repo
```bash=
# Clone remote repository
git clone <repo uri>
# checkout master
git checkout master
# show changes
git status
# make changes on different branch. git branch <branch name> && git checkout <branch name>
git checkout -b <branch name>
# when changes are done add changes to index
git add -u (add all unstaged changes)
git add <file path - eg. path shown in git status>
# commit changes to local repository
git commit -m "imperative comment"
# git fetch current state from remote repository master
git fetch
# merge local commit(s) inside local repository with fetched state
git rebase origin/master
# push current local master to remote repository
git push origin master:refs/for/master
# push current HEAD to remote repository
git push origin HEAD:refs/for/master
# add new changes to already committed (and pushed change)
git commit --amend
# if necessary add comments and exit vi ":wq"
git fetch
git rebase origin/master
git push origin HEAD:refs/for/master
```
3. Reset all to remote master without loosing untracked changes
```bash=
# clean workspace and store unstaged files in stash
git stash
# update local repo to remote repo
git fetch
# reset to updated local master
git reset --hard origin/master
# bring back stashed files to workspace
git stash apply
```
4. Reset a single file
```bash=
# Not added to index
git checkout -- filename
# added to index, but not committed
git reset HEAD filename
git checkout -- filename
# file already committed -> reset to local master
git checkout origin/master filename
```
5. Reset master branch to a certain commit
```bash=
# Resets index to former commit
git reset --hard <commit_id>
# Moves pointer back to previous HEAD and stages former versions of files, that have changed
git reset --soft HEAD@{1}
git commit -m "Revert to <commit_id>"
```
6. **Squash** - Combine multiple local commits to push the with single changeId
```bash=
# If several commits are already pushed for review, go to Gerrit and abandon all changeIds
# squash the commits. Here '3' is the number of commits that are squashed together
git rebase -i HEAD~3
# push for review
git push origin master:refs/for/master
```
7. Commit and push from a computer without personal configuration
```bash=
git add
git commit -m "message" --author="name.surname<name.surname@email.com>"
git fetch
git rebase
git push origin HEAD:refs/for/master
```
8. Try something on remote computer - Push for draft, cherrypick, commit and push for refs
**git cherry-pick** is a powerfull command that enables arbitrary Git commits to be picked by reference and appended to the current working HEAD
```bash=
# On local computer
git add
git commit -m "message"
git push origin master:refs/drafts/master
# If the repo is not already downloaded
git clone <repo>
git checkout master
# Copy link from gerrit and execute
# the link can be found in the top right corner (click "Download" and choose the 'Cherry pick' option)
git fetch <repo> refs/changes/... && git cherrypick FETCH_HEAD ...
# push changes from pc without personal git config to remote repository
git add
git commit -m "message" --author="name.surname<name.surname@email.com>"
git fetch
git rebase
git push origin master:refs/for/master
```
## 3. gerrit
hcp5-sources.int.esrlabs.com/Documentation/intro-how-gerrit-works.html
1. Basic project usage
a. Create a local branch, e.g. new_feature
```bash=
git checkout -b new_feature
```
b. Add files to your branch
```bash=
git add sample.java
```
c. Create commit and insert commit message
```bash=
git commit -v
```
Format:
First line: specify what was modified, briefly. E.g.: Created documentation for X
Second line: leave a blank line
Third line: ID of the ticket (e.g AHCP5-12345)
Example:
```
Created documentation for HMI
AHCP-12345
```
d. to reverse a commit and modify last commit made
```bash=
# this will unstage files which were added to your last commit
git reset HEAD~1
```
e. To edit your commit message
```bash=
git commit --amend
```
2. **gerrit "magic branches"** and pull requests
a. To create a pull request on gerrit, "magic branches" have to be used, a magic branch as such is refs/for/master
Beware that refs/for/master is the actual name of the branch, to not be confused with "master" -> this will push your changes **directly** into master instead of creating a pull request
a2. when a good unit of work is complete and you have more intemediate commits for that already than required, you might want to squash via
```bash=
git rebase -i
```
**git rebase** - lets users integrate changes from one branch to another
**-i** - make a list of the commits which are about to be rebased. Let the user edit that list before rebasing.
b. Creating a pull request:
:::spoiler template
```bash=
git push <remote-name> <branch>:refs/for/<target-branch>
```
:::
```bash=
# this will create a pull request, link to the PR
# can be found inside the terminal after creating said PR
git push gerrit HEAD:refs/for/master
```

c. Adding modifications to a pull request
```bash=
# where 12345 is the ID of the pull request
git checkout -b change-12345
```

or you can also go into your pull request, click on the three dots from top-right corner

Download patch -> copy the first URL from there (labeled branch)

Can be also done with
```bash=
# unstage files added to last commit
//git reset HEAD~1
# to edit commit message
git commit -ammend
# again and it will be considered as a new revision of the changeset
git push gerrit HEAD:/refs/for/master
```
Add your changes via git add then use git commit --amend (**ChangeId has to be the same as in the initial commit!**)