---
# System prepended metadata

title: GIT筆記
tags: [git]

---


# GIT note

- 目錄
    - [clone](#clone)
    - [pull](#pull)
    - [push](#push)
    - [remote](#remote)
    - [submodule](#submodule)
    - [lfs](#lfs)
    - [reset](#reset)
    - [reflog](#reflog)
    - [stash](#stash)
    - [branch](#branch)
    - [upstream](#upstream)
    - [bisect](#bisect)
    - [diff] (#diff)
# 建立新res
linux:
http://wiki.csie.ncku.edu.tw/github
windowns:
https://dotblogs.com.tw/kirkchen/2013/04/23/use_ssh_to_interact_with_github_in_windows

# rebase
https://nulab.com/zh-tw/learn/software-development/git-tutorial/git-collaboration/integrating-branches/rebasing-branches/
# merge
https://nulab.com/zh-tw/learn/software-development/git-tutorial/git-collaboration/integrating-branches/merging-branches/
## rebase vs merge
https://www.maxlist.xyz/2020/05/02/git-merge-rebase/

---

# log
```
git log 
```
## --oneline
show oneline log
## -p
see detail

# clone
使用說明:從遠端複製程式碼下來
https://shengyu7697.github.io/git-clone-specific-branch/
ex:
```shell=
$ git clone https://github.com/sc2liao/fibdrv
```



# pull
- pull request
https://gitbook.tw/chapters/github/pull-request

將遠端的檔案更新並複製到local端的檔案

- git pull runs git fetch with the given parameters and calls git merge to merge the retrieved branch heads into the current branch

:::info
:+1: pull=fetch+merge 
:::
[offical document](https://git-scm.com/docs/git-pull)

**example:**
```shell
$ git pull
```

或
```shell
$ git pull origin master
```
成功訊息:
``` shell 
$ git pull
已經是最新的。
```

*    git pull --rebase
加上rebase不會多出一個merge point
# push
https://zlargon.gitbooks.io/git-tutorial/content/remote/upstream.html
## parameter
- -u : set upstream
```
git push <remote> <local branch name>:<remote branch want to push into>
```
ex:
```
$ git push origin master
```
表示將local的master推到remote端的master，若master不存在會被新建

如果省略本地分支名，则表示删除指定的远程分支，因为这等同于推送一个空的本地分支到远程分支。
ex:
```
git push origin :<要刪除的branch名稱>
```
https://gitbook.tw/chapters/github/delete-remote-branch
```
$ git push origin
```
將當前的branch推到remote對應的branch(預設推送到相同名稱)
```
$ git push
```
如果當前只有一個追蹤的branch，則可省略主機名稱


https://gitbook.tw/chapters/github/push-to-github
# remote
使用 
```
$ git remote -v
```
檢視遠端資料庫狀態(顯示真正連線哪一個專案)
參考資料
[github ducutment](http://onlywei.github.io/explain-git-with-d3/)

- 增加遠端資料庫
```
$ git remote add <遠端命名> <要新增的url>
```
<遠端命名>:可以自行取名 通常會叫做'origin'
<要新增的url>:github上要clone時的url

https://andy6804tw.github.io/2019/01/04/git-remove-remote/
## set-url
改變remote端庫:
```
$git remote set-url <要改的遠端命名> <要連結的遠端庫>
```

ex:
```
git remote set-url origin git@github.com:sc2liao/linux.git
```

## remote add
```
git remote add
```

# submodule 

## update
```
$git submodule update --init --recursive
```
加上這個指令可以將整個PROJECT中的子項目一起更新 後面的--recursive是遞迴的抓(如果SUBMODULE裡面還有SUBMODULE會一起更新

http://jhjguxin.github.io/blog/2012/04/19/git-submodule-de-ren-shi-yu-zheng-que-shi-yong-!/
## add
https://blog.longwin.com.tw/2015/05/git-submodule-add-remove-2015/
- example:
git submodule add -f --name mypath/submodulename -b myassignbranch git@mygithost:billboard  mypath/mysubmodule

https://chrisjean.com/git-submodules-adding-using-removing-and-updating/
### --name
assign submodulename
### -b
assign branch
### -f
force overwrite

## remove
```git=
git rm -fr pear/facebook-php-sdk/
```
這邊的意思是移除pear目錄下的facebook-php-sdk這個submodule
___
# lfs
GIT在上傳或是下載時 較大的檔案可能會用linker的方式存在，因此檔案中可能會出現"假的"檔案，因此需要git lfs來將原始檔案抓下來
*    install
```
$apt install git-lfs
```
如果出現錯誤:
```
root@Ubuntu20_04:/src# apt install git-lfs
Reading package lists... Done
Building dependency tree
Reading state information... Done
E: Unable to locate package git-lfs
```
執行更新
```
sudo apt-get update -y
```
再重裝一次
或是直接到:https://github.com/git-lfs/git-lfs/releases
抓取原始碼安裝
```
tar -xzvf git-lfs-linux-arm64-v2.8.0.tar.gz
sudo ./install.sh
```
安裝完成後再來到對應的目錄下執行:
```
$git lfs pull
```
or
```
foreach git lfs pull
```
將該檔案還原成原本的檔案
:accept: lfs意思是GIT針對大檔案的處理(lfs= Large File Storage)

# commit

## bisect 
快速找到第一個有問題的 Commit

https://www.gss.com.tw/blog/%E4%BD%BF%E7%94%A8-git-bisect-%E5%BF%AB%E9%80%9F%E6%89%BE%E5%88%B0%E7%AC%AC%E4%B8%80%E5%80%8B%E6%9C%89%E5%95%8F%E9%A1%8C%E7%9A%84-commit

## amend
附加內容到前面的commit上
git commit --amend
    
## cherry-pick
把其他branch的commit加入到目前的branch中
git cherry-pick


## reflog
假使我們用了 git reset 語法，將版本還原到前面的版本，而且用 git log 上看也看不到那些紀錄。但此時你又想把 commit 救回來該怎麼辦？

此時你可以用 git reflog 指令，它會詳細顯示你每個指令的 SHA-1
```
git reflog
```

https://w3c.hexschool.com/git/10bf7677.
___
# stash
stash(藏)指的是暫存的意思
```
git stash
```
or
```
git stash pop
```

https://backlog.com/git-tutorial/tw/intro/intro1_1.html

https://gitbook.tw/chapters/faq/stash

https://kingofamani.gitbooks.io/git-teach/content/chapter_3_branch/stash.html
如果發現暫存太多想要全部刪除的話
```
git stash clear
```
https://blog.csdn.net/csdnmuyi/article/details/80237173
# checkout
可以使用checkout還原某個檔案
```
git checkout HEAD^ -- filename.cpp
```
這個指令的意思是 還原filename.cpp這個檔案到目前HEAD往前一個commit的狀態
## checkout
使用checkout 可以些換branch或是commit 
ex: 切換回master
```
git checkout master
```
note:使用checkout 指令移動的是HEAD 使用branch移動的是整個branch放在哪個commit上
- 使用rebase 搬動某個branch的其中幾則commit到某個commit(或branch)上

```
git rebase --onto <mybranch> HEAD^^
```
上面這段的意思為將目前所在的branch搬動兩則commit 到mybranch上(這個動作不會移動HEAD位置)
舉例來說 假設目前在branch A上 從A上搬動一則commit到 branch B上 則實際產生結果:
使用git branch看會看到還在branch A上 看commit圖(git graph)會看到在branch B的最新commit上多了一則剛剛搬動的branch上的commit，義即branch A的歷程除了第一則搬動的commit外都不同了。
ex:
```git=
git checkout {origin_commit_hash}

git checkout -b aaa

git add {adjust_file}

git commit --amend -m " xxx"

git checkout {mr_branch}

git rebase --onto aaa HEAD^^^
```
---

# reset
可以移動到某個commit
Discard the local changes
```
git reset <SHA-1編號> --hard
```
還原到某個 commit但不保留
or
```
git checkout -t -f (remote name/ remote branch name)
```

https://www.maxlist.xyz/2020/05/03/git-reset-checkout/
也可以使用reset還原某個檔案狀態:
```
git reset filename.cpp
```
這個的意思是原本filename.cpp可能是track的狀態 可以使filename.cpp狀態更改為untrack
https://zlargon.gitbooks.io/git-tutorial/content/file/recover.html
# branch
通常適用於開發新功能時，branch跟commit是兩個分開的功能，commit全部都存在git中 branch則是可以選擇指向不同的commit並不是一個branch存著不同的commit
https://zlargon.gitbooks.io/git-tutorial/content/branch/create_delete.html
git branch -r 查看遠端branch
```
origin/HEAD -> origin/master
  origin/master
  origin/squash_test
```
git checkout -b squash_test1 origin/squash_test

將local 端squash_test1連結到遠端origin/squash_test
## 建立branch


```
$git branch <branchname>
```
or
```
$git checkout -b <branchname>
```


- 在遠端建立branch
```
git clone git@github.com:user/project.git
cd project
git checkout -b new_branch # 建立 local branch
git push -u origin new_branch # 建立遠端 branch (將 new_branch 建立到遠端)
git fetch
vim index.html # 修改
git commit -m 'test' -a # commit
git push
```
註: new_branch 要換成你要的 branch name, 以上所有 new_branch 都要對應著修改成同樣名稱.
https://blog.longwin.com.tw/2013/11/git-create-remote-branch-2013/

## 刪除branch:
```bash=
$git branch -d <branchname>
```
- 刪除遠端branch
使用
```
git push origin :<branch name>
```
由於使用git push origin master:(branch name)
指的是建立名稱 將master拿掉等同於推一個空的到該branch上
https://gitbook.tw/chapters/github/delete-remote-branch
## rename branch
可以重新命名branch 不管目前在哪一個branch都可以操作
ex:
```bash
git branch -m (old_branch_name) (new_branch name)
```

___
# upstream
https://www.delftstack.com/zh-tw/howto/git/set-upstream-in-git/

https://zlargon.gitbooks.io/git-tutorial/content/remote/upstream.html

https://gitbook.tw/chapters/github/syncing-a-fork

從遠端upstream更新local
- 適用情境:
當有其他開發者更新了master分支，可以運用此方式將更新過後的分支update到自己fork出來的project或是local的project
https://www.atlassian.com/git/tutorials/git-forks-and-upstreams
---
# diff

常用 git diff 用法
git diff: 显示工作目录 (Working Directory) 与暂存区 (Staging Area) 之间的差异。
场景: 查看你修改了文件，但还没 git add 之前的改动。
git diff --cached 或 git diff --staged: 显示暂存区 (Staging Area) 与上一次提交 (HEAD) 之间的差异。
场景: 查看 git add 之后、git commit 之前，哪些内容被暂存了，用于最终检查。
git diff <commit2: 比较两个提交记录之间的差异。
场景: 比较两个历史版本，了解特定分支或时间点的变化。
git diff <file: 只显示特定文件的差异。
场景: 只关心某个文件的修改，不看其他文件。
git diff HEAD<file: 比较工作目录中某个文件与 HEAD (上次提交) 的差异。

---
# log

https://git-scm.com/docs/git-log
https://git-scm.com/book/zh-tw/v2/Git-%E5%9F%BA%E7%A4%8E-%E6%AA%A2%E8%A6%96%E6%8F%90%E4%BA%A4%E7%9A%84%E6%AD%B7%E5%8F%B2%E8%A8%98%E9%8C%84

# blame

# config
## adjust the commit log message char
git config core.commentchar "<char>"
    
### change edtior to vim
git config --global core.editor "vim"
    
git config --global core.excludesfile 
    
git push --set-upstream origin xv6_dev
    
    

    
# git 2FA
https://ginnyfahs.medium.com/github-error-authentication-failed-from-command-line-3a545bfd0ca8
###### tags: `git`