---
# System prepended metadata

title: Git
tags: [Version Control, QCT, Linux Tools]

---

Git
===

###### tags: `Linux Tools` `Version Control` `QCT`

### Open Source Contribution Guideline
#### Copy from upstream
1. Fork repository from upstream
2. Git clone self repository on local machine
3. Create new branch from local repository
4. Modify then Git push new branch to self repository
5. Merge request new branch of self repository into upstream repository
#### Synchronize with upstream
```
git fetch remote_repos remote_master:try_merge
git diff local_master try_merge
git merge try_merge
git branch -d try_merge
```
:::info
```git merge``` incorporates changes from the named commits (since the time their histories diverged from the current branch) into the current branch.
```git diff <old> <new>```
:::
#### Add new feature
1. Test if new feature conflicts with main branch
```
git checkout try_feature
git rebase master
git add/rm <conflicted_files>
git rebase --continue/--abort
# git checkout master
# git merge try_feature
```
2. Push new feature to self remote repository
3. Merge request new feature of self repository into upstream repository
#### [Modify remote commits](https://gist.github.com/gunjanpatel/18f9e4d1eb609597c50c2118e416e6a6)
```
git push origin +13191bcf^:master
```
:::info
* ```13191bcf``` is latest remote commit.
* ```x^``` as the parent of ```x```.
* ```+``` as a forced non-fastforward push.
:::

### Discard changes before commit
* Remove untracked file from the working tree
```
git clean -f FILE
```
* Remove untracked directory from the working tree
```
git clean -fd DIR
```
* Remove tracked file from the working tree
```
git checkout -- FILE
```

### Discard files in the commit
```
git checkout EARLY_COMMIT_HASH
git rm --cached FILE
git commit --amend -m "Remove file"
git branch NEW_BRANCH
git cherry-pick LATER_COMMIT_HASH
```

### Modify Commits
1. 合併為某次commit 
```
git rebase -i <早於某次commit的commit>
```
2. pick改squash
```
pick f7f3f6d changed my name a bit
squash 310154e updated README formatting and added blame
squash a5f4a0d added cat-file
```
3. 改commit訊息 
```
git commit --amend
git rebase --continue
```
4. 改寫第一次commit
```
git rebase -i --root master
```
5. pick改edit
```
edit f7f3f6d changed my name a bit
pick 310154e updated README formatting and added blame
pick a5f4a0d added cat-file
```
6. 改commit訊息
```
git commit --amend
git rebase --continue
```
7. 推到遠端
```
git push --force origin master
```

### Diff
- vimdiff
  * **Ctrl W + Ctrl W** - switch to the other split window
```
# cat .git/config
[diff]
        tool = vimdiff
[difftool]
        prompt = false
[alias]
        d = difftool
# git d
```
- [Show changes between commits, commit and working tree, etc](https://git-scm.com/docs/git-diff)
1. 比較目錄下所有檔案
沒有staged和預設為上一個commit的更改比例
```git diff --dirstat=lines <commit>```
2. 比較兩個不一樣的檔案
可以是外部檔案
```git diff --no-index <path> <path>```
3. 比較同一個檔案，但是不同版本
   1. staged和預設為上一個commit的差別
   ```git diff --cached <commit> <path>```
   2. 沒有staged和預設為上一個commit的差別
   ```git diff <commit> <path>```
   3. staged和沒有staged的差別
   ```git diff <path>```
   4. 不同branch tip的差別
   ```git diff mybranch..master -- myfile.cs```
   5. branch common base與tip的差別
   ```git diff mybranch...master -- myfile.cs```
   (```git diff A...B``` is equivalent to ```git diff $(git-merge-base A B) B```)
- [Inspecting Changes with Diffs](https://www.git-tower.com/learn/git/ebook/en/command-line/advanced-topics/diffs)
- [How to: Colours in Git](https://nathanhoad.net/how-to-colours-in-git)

### Show current info
* Current branch: ```git rev-parse --abbrev-ref HEAD```
* Curremt commit: ```git rev-parse --short HEAD```
* Committed files: ```git ls-files '*.go'```
* Tag
```
# git describe --tags
tag1-2-g026498b
```
:::info
```tag1```: 最近的tagname
```2```: 表示```tag1```之後有2次commit
```g```: 代表管理工具git
```026498b```: 最新commit
:::

### Reference
- [How can I reconcile detached HEAD with master/origin?](https://stackoverflow.com/questions/5772192/how-can-i-reconcile-detached-head-with-master-origin)
- [Patch 管理](https://zlargon.gitbooks.io/git-tutorial/content/patch/)
- [How to undo (almost) anything with Git](https://github.com/blog/2019-how-to-undo-almost-anything-with-git)
- [Git worktree: 同時開多個工作目錄](https://ihower.tw/blog/archives/8740)
- [Fetch 指令才是把東西拉回來的主角](https://gitbook.tw/chapters/github/pull-from-github.html)
- [儲藏 (Stashing)](https://git-scm.com/book/zh-tw/v1/Git-%E5%B7%A5%E5%85%B7-%E5%84%B2%E8%97%8F-Stashing)
- [使用 rebase 合併](https://backlog.com/git-tutorial/tw/stepup/stepup2_8.html)
- [Commit Tree - Cherry Pick Usage](https://github.com/zlargon/git-tutorial/blob/master/branch/commit_tree.md)

