---
title: Tips to Git
tags: Git
---
# Git Tips
## Tag
https://gitbook.tw/chapters/tag/using-tag.html
- milestone 的建立
- 通常應用於 version, i.e., `1.0.0`, `beta-test`
- 有 lightweight tag 和 annotated tag
- lightweight tag
- `git tag <tag_name> <commit_sha-1>`
- `git tag <tag_name>` 會在在目前 commit 之上
- 指向 commit
- annotated tag
- `git tag <tag_name> <commit_sha-1> -am "<Describption>"`
- 指向 Tag 物件 (Tag 物件 指向 commit)
- ==Annotated tags are meant for release while lightweight tags are meant for private or temporary object labels.==
- 存放位置為 `.git/refs/tags`
### :+1: lightweight tagging
```bash=
git tag <tag_name> <commit_sha-1>
git tag <tag_name>
```
### :+1: annotated tagging
```bash=
git tag <tag_name> <commit_sha-1> -am "<Describption>"
git tag <tag_name> -am "<Describption>"
```
### delete tag
```bash=
git tag -d <tag_name>
```
## 從零操作 branch 之開發流程
### prerequisites
- master 需要權限管控, 不能讓所有 developers checkout
- master 會在 release 之後 push, 在 release 時就該把 QA testing 執行完成
- 只有 master 可以執行 CD
- 所有 branches 都可以執行 CI
### step
1. 開發者開始工作, 從 master 拉一個 dev 分支
```bash=
git checkout -b dev master
```
2. 開發者需要在 dev 分支上開發新功能 x, 從 dev 拉一個 feature 分支
```bash=
git checkout -b feature-x dev
```
3. 開發完成後, 將 feature-x merge 到 dev branch
```bash=
git checkout dev
git merge –-no-ff feature-x
```
4. 刪除之前的 feature-x branch
```bash=
git branch -d feature-x
```
5. 假設功能備妥, 在合併到 master 之前, 發佈到 release branch
```bash=
git checkout -b release-1.0 dev
```
6. 檢查過後沒問題, 再合併到 master 分支
```bash=
git checkout master
git merge –-no-ff release-1.0
```
7. 建立標籤, 標註當前合併過後的新節點
```bash=
git tag -a 1.0
```
8. 合併到 dev branch
```bash=
git checkout dev
git merge -–no-ff release-1.0
```
9. 刪除 release 分支
```bash=
git branch -d release-1.0
```
:::info
add-on: `--no-ff` 加與不加的差別

- https://stackoverflow.com/questions/9069061/what-is-the-difference-between-git-merge-and-git-merge-no-ff/21717431#21717431
- https://medium.com/@fcamel/%E4%BD%95%E6%99%82%E8%A9%B2%E7%94%A8-git-merge-no-ff-d765c3a6bef5
:::
## automatically login
local setting:
```bash=
git config credential.helper store
```
global setting:
```bash=
git config credential.helper "store --file ./.git/credentials"
```
## switch to remote branch
```bash
git checkout --track origin/branch
```
> `git fetch origin` or `git fetch --all` , this will fetch all the remote branches to your local and then this the second option you can proced with.
## fetch remote branch
```bash=
git remote -v
git remote set-url origin https://github.com/<USERNAME>/<OTHER_REPOSITORY>.git
```
## create a branch from another branch
Creates MyFeature branch off dev
```bash=
git checkout -b myFeature dev
git commit -m "Your message"
git push origin myFeature
```
## exchange remote branch
```bash=
# Rename the local branch to the new name
git branch -m <old_name> <new_name>
# Delete the old branch on remote - where <remote> is, for example, origin
git push <remote> --delete <old_name>
# Or shorter way to delete remote branch [:]
git push <remote> :<old_name>
# Prevent git from using the old name when pushing in the next step.
# Otherwise, git will use the old upstream name instead of <new_name>.
git branch --unset-upstream <old_name>
# Push the new branch to remote
git push <remote> <new_name>
# Reset the upstream branch for the new_name local branch
git push <remote> -u <new_name>
```
## delete remote branches
```bash=
git branch -a
git push origin --delete test
```
## merge to dev
```bash=
git merge -–no–ff dev
```
## git add
https://stackoverflow.com/questions/572549/difference-between-git-add-a-and-git-add
| git add -A | git add . | git add -u |
| -------- | -------- | -------- |
|-A, --all||-u, --update|
| stages all changes | stages new files and modifications, without deletions (on the current directory and its subdirectories) | stages modifications and deletions, without new files |
:::success
==git add -A== is equivalent to ==git add . ; git add -u==
:::
### Git 1.X

### Git 2.X

## 撤銷 commit
https://gitbook.tw/chapters/rewrite-history/reset-revert-and-rebase.html
| command | modify history? | when? | deps. |
| -------- | -------- | -------- | -------- |
| reset | yes | push 前 |回到某個commit狀態|
| rebase | yes | push 前 |回到某個commit狀態, 方便整理舊有的branches|
| revert | no | push 後 |回到某個commit狀態, 並新增一個 commit, 安全性最高|
- 通常 `reset` 就夠用, 可以作為 default 撤銷手段
- `rebase` 有需求才使用
- `revert` 適合大型專案
## Deploy Key vs Deploy Token
| Deploy Key | Deploy Token |
| -------- | -------- |
| 可以共享 projects 或不同 groups|專屬於 project or group|
|SSH key產生於本機|GitLab創建,僅提供一次使用|
|不允許rw|允許rw|