git

是目前世界上最先進的分佈式版本控制系統

補充說明

git命令 很多人都知道,Linus在1991年創建了開源的Linux,從此,Linux系統不斷發展,已經成爲最大的服務器系統軟件了。

Linus雖然創建了Linux,但Linux的壯大是靠全世界熱心的志願者參與的,這麼多人在世界各地爲Linux編寫代碼,那Linux的代碼是如何管理的呢?

事實是,在2002年以前,世界各地的志願者把源代碼文件通過diff的方式發給Linus,然後由Linus本人通過手工方式合併代碼!

你也許會想,爲什麼Linus不把Linux代碼放到版本控制系統裏呢?不是有CVS、SVN這些免費的版本控制系統嗎?因爲Linus堅定地反對CVS和SVN,這些集中式的版本控制系統不但速度慢,而且必須聯網才能使用。有一些商用的版本控制系統,雖然比CVS、SVN好用,但那是付費的,和Linux的開源精神不符。

不過,到了2002年,Linux系統已經發展了十年了,代碼庫之大讓Linus很難繼續通過手工方式管理了,社區的弟兄們也對這種方式表達了強烈不滿,於是Linus選擇了一個商業的版本控制系統BitKeeper,BitKeeper的東家BitMover公司出於人道主義精神,授權Linux社區免費使用這個版本控制系統。

安定團結的大好局面在2005年就被打破了,原因是Linux社區牛人聚集,不免沾染了一些梁山好漢的江湖習氣。開發Samba的Andrew試圖破解BitKeeper的協議(這麼幹的其實也不只他一個),被BitMover公司發現了(監控工作做得不錯!),於是BitMover公司怒了,要收回Linux社區的免費使用權。

Linus可以向BitMover公司道個歉,保證以後嚴格管教弟兄們,嗯,這是不可能的。實際情況是這樣的:

Linus花了兩週時間自己用C寫了一個分佈式版本控制系統,這就是Git!一個月之內,Linux系統的源碼已經由Git管理了!牛是怎麼定義的呢?大家可以體會一下。

Git迅速成爲最流行的分佈式版本控制系統,尤其是2008年,GitHub網站上線了,它爲開源項目免費提供Git存儲,無數開源項目開始遷移至GitHub,包括jQuery,PHP,Ruby等等。

歷史就是這麼偶然,如果不是當年BitMover公司威脅Linux社區,可能現在我們就沒有免費而超級好用的Git了。

Git常用命令清單

語法

1git [--version] [--help] [-C <path>] [-c name=value] [--exec-path[=<path>]] [--html-path] [--man-path] [--info-path] [-p | --paginate | --no-pager] [--no-replace-objects] [--bare] [--git-dir=<path>] [--work-tree=<path>] [--namespace=<name>] <command> [<args>]

選項

 1add              將文件內容添加到索引
 2bisect           通過二進制查找引入錯誤的更改
 3branch           列出,創建或刪除分支
 4checkout         檢查分支或路徑到工作樹
 5clone            將存儲庫克隆到新目錄中
 6commit           將更改記錄到存儲庫
 7diff             顯示提交,提交和工作樹等之間的更改
 8fetch            從另一個存儲庫下載對象和引用
 9grep             打印匹配圖案的行
10init             創建一個空的Git倉庫或重新初始化一個現有的
11log              顯示提交日誌
12merge            加入兩個或更多的開發歷史
13mv               移動或重命名文件,目錄或符號鏈接
14pull             從另一個存儲庫或本地分支獲取併合並
15push             更新遠程引用以及相關對象
16rebase           轉發端口本地提交到更新的上游頭
17reset            將當前HEAD復位到指定狀態
18rm               從工作樹和索引中刪除文件
19show             顯示各種類型的對象
20status           顯示工作樹狀態
21tag              創建,列出,刪除或驗證使用GPG簽名的標籤對象

例子

init

git init #初始化

status

git status #獲取狀態

add

git add file # .或*代表全部添加
git rm --cached <added_file_to_undo> # 在commit之前撤銷git add操作
git reset head # 好像比上面git rm --cached更方便

commit

git commit -m "message" #此處注意亂碼

remote

git remote add origin [email protected]:JSLite/test.git #添加源

push

1git push -u origin master # push 同時設置默認跟蹤分支  
2git push origin master  
3git push -f origin master # 強制推送文件,縮寫 -f(全寫--force)

clone

git clone git://github.com/JSLite/JSLite.js.git
git clone git://github.com/JSLite/JSLite.js.git mypro #克隆到自定義文件夾
git clone [user@]example.com:path/to/repo.git/ #SSH協議還有另一種寫法。

git clone支持多種協議,除了HTTP(s)以外,還支持SSH、Git、本地文件協議等,下面是一些例子。git clone <版本庫的網址> <本地目錄名>

1git clone http[s]://example.com/path/to/repo.git/
2git clone ssh://example.com/path/to/repo.git/
3git clone git://example.com/path/to/repo.git/
4git clone /opt/git/project.git 
5git clone file:///opt/git/project.git
6git clone ftp[s]://example.com/path/to/repo.git/
7git clone rsync://example.com/path/to/repo.git/

配置

首先是配置帳號信息 ssh -T [email protected] 測試。

修改項目中的個人信息

1git help config # 獲取幫助信息,查看修改個人信息的參數  
2git config --global user.name "小弟調調"           # 修改全局名字
3git config --global user.email "[email protected]"  # 修改全局郵箱
4git config --list         # 查看配置的信息  

配置自動換行

自動轉換坑太大,提交到git是自動將換行符轉換爲lf

1git config --global core.autocrlf input

常見使用場景

創建SSH密鑰

這個密鑰用來跟 github 通信,在本地終端裏生成然後上傳到 github

1ssh-keygen -t rsa -C '[email protected]' # 生成密鑰  
2ssh-keygen -t rsa -C "[email protected]" -f ~/.ssh/ww_rsa # 指定生成目錄文件名字
3ssh -T [email protected] # 測試是否成功  

多賬號ssh配置

1.生成指定名字的密鑰

ssh-keygen -t rsa -C "郵箱地址" -f ~/.ssh/jslite_rsa
會生成 jslite_rsajslite_rsa.pub 這兩個文件

2.密鑰複製到託管平臺上

vim ~/.ssh/jslite_rsa.pub 打開公鑰文件 jslite_rsa.pub ,並把內容複製至代碼託管平臺上

3.修改config文件

vim ~/.ssh/config #修改config文件,如果沒有創建 config

 1Host jslite.github.com
 2  HostName github.com
 3  User git
 4  IdentityFile ~/.ssh/jslite_rsa
 5
 6Host work.github.com
 7  HostName github.com
 8  # Port 服務器open-ssh端口(默認:22,默認時一般不寫此行)
 9  # PreferredAuthentications 配置登錄時用什麼權限認證 
10  #                          publickey|password publickey|keyboard-interactive等
11  User git
12  IdentityFile ~/.ssh/work_rsa
  • Host 這裏是個別名可以隨便命名
  • HostName 一般是網站如:[email protected]:username/repo.git 填寫 github.com
  • User 通常填寫git
  • IdentityFile 使用的公鑰文件地址

4.測試

1ssh -T [email protected]  # `@`後面跟上定義的Host  
2ssh -T work.github.com        # 通過別名測試
3ssh -i ~/公鑰文件地址 Host別名  # 如 ssh -i ~/.ssh/work_rsa work.github.com

5.使用

1# 原來的寫法
2git clone [email protected]:<jslite的用戶名>/learngit.git
3# 現在的寫法
4git clone [email protected]:<jslite的用戶名>/learngit.git
5git clone [email protected]:<work的用戶名>/learngit.git

5.注意

如果你修改了id_rsa的名字,你需要將ssh key添加到SSH agent中,如:

1ssh-add ~/.ssh/jslite_rsa
2ssh-add -l  # 查看所有的key
3ssh-add -D  # 刪除所有的key
4ssh-add -d  ~/.ssh/jslite_rsa # 刪除指定的key

免密碼登錄遠程服務器

1ssh-keygen -t rsa -P '' -f ~/.ssh/aliyunserver.key
2ssh-copy-id -i ~/.ssh/aliyunserver.key.pub [email protected] # 這裏需要輸入密碼一次

編輯 ~/.ssh/config

1Host aliyun1
2  HostName 192.168.182.112
3  User root
4  PreferredAuthentications publickey
5  IdentityFile ~/.ssh/aliyunserver.key

上面配置完了,可以通過命令登錄,不需要輸入IP地址和密碼 ssh aliyun1

https協議下提交代碼免密碼

1git clone https://github.com/username/rep.git

通過上面方式克隆可能需要密碼,解決辦法:進入當前克隆的項目 vi rep/.git/config 編輯 config, 按照下面方式修改,你就可以提交代碼不用輸入密碼了。

 1[core]
 2 repositoryformatversion = 0
 3 filemode = true
 4 bare = false
 5 logallrefupdates = true
 6 ignorecase = true
 7 precomposeunicode = true
 8[remote "origin"]
 9- url = https://github.com/username/rep.git
10+ url = https://用戶名:密碼@github.com/username/rep.git
11 fetch = +refs/heads/*:refs/remotes/origin/*
12[branch "master"]
13 remote = origin
14 merge = refs/heads/master

文件推向3個git庫

1. 增加3個遠程庫地址

1git remote add origin https://github.com/JSLite/JSLite.git  
2git remote set-url --add origin https://gitlab.com/wang/JSLite.js.git  
3git remote set-url --add origin https://oschina.net/wang/JSLite.js.git  

2. 刪除其中一個 set-url 地址

1usage: git remote set-url [--push] <name> <newurl> [<oldurl>]
2   or: git remote set-url --add <name> <newurl>
3   or: git remote set-url --delete <name> <url>

git remote set-url --delete origin https://oschina.net/wang/JSLite.js.git

3.推送代碼

1git push origin master
2git push -f origin master  # 強制推送  

4.拉代碼

只能拉取 origin 裏的一個url地址,這個fetch-url
默認爲你添加的到 origin的第一個地址

1git pull origin master   
2git pull --all # 獲取遠程所有內容包括tag  
3git pull origin next:master # 取回origin主機的next分支,與本地的master分支合併  
4git pull origin next # 遠程分支是與當前分支合併  
5
6# 上面一條命令等同於下面兩條命令   
7git fetch origin  
8git merge origin/next  

如果遠程主機刪除了某個分支,默認情況下,git pull 不會在拉取遠程分支的時候,刪除對應的本地分支。這是爲了防止,由於其他人操作了遠程主機,導致git pull不知不覺刪除了本地分支。
但是,你可以改變這個行爲,加上參數 -p 就會在本地刪除遠程已經刪除的分支。

1$ git pull -p
2# 等同於下面的命令
3$ git fetch --prune origin 
4$ git fetch -p

5.更改pull

只需要更改config文件裏,那三個url的順序即可,fetch-url會直接對應排行第一的那個utl連接。

修改遠程倉庫地址

1git remote remove origin  # 刪除該遠程路徑  
2git remote add origin [email protected]:JSLite/JSLite.git  # 添加遠程路徑 

撤銷遠程記錄

1git reset --hard HEAD~1 # 撤銷一條記錄   
2git push -f origin HEAD:master # 同步到遠程倉庫  

放棄本地的文件修改

1git reset --hard FETCH_HEAD # FETCH_HEAD表示上一次成功git pull之後形成的commit點。然後git pull

git reset --hard FETCH_HEAD 出現錯誤

1git pull
2You are not currently on a branch, so I cannot use any
3'branch.<branchname>.merge' in your configuration file.
4Please specify which remote branch you want to use on the command
5line and try again (e.g. 'git pull <repository> <refspec>').
6See git-pull(1) FOR details.

解決方法:

1git checkout -b temp # 新建+切換到temp分支 
2git checkout master

最簡單放棄本地修改內容

1# 如果有的修改以及加入暫存區的話
2git reset --hard 
3# 還原所有修改,不會刪除新增的文件
4git checkout . 
5# 下面命令會刪除新增的文件
6git clean -xdf

通過存儲暫存區stash,在刪除暫存區的方法放棄本地修改。

1git stash && git stash drop 

回滾到某個commit提交

1git revert HEAD~1 # 撤銷一條記錄 會彈出 commit 編輯
2git push # 提交回滾

回退到某一個版本

1git reset --hard <hash>
2# 例如 git reset --hard a3hd73r
3# --hard代表丟棄工作區的修改,讓工作區與版本代碼一模一樣,與之對應,
4# --soft參數代表保留工作區的修改。

去掉某個commit

1# 實質是新建了一個與原來完全相反的commit,抵消了原來commit的效果
2git revert <commit-hash> 

新建一個空分支

1# 這種方式新建的分支(gh-pages)是沒有 commit 記錄的
2git checkout --orphan gh-pages
3# 刪除新建的gh-pages分支原本的內容,如果不刪除,提交將作爲當前分支的第一個commit
4git rm -rf .
5# 查看一下狀態 有可能上面一條命令,沒有刪除還沒有提交的的文件
6git state 

合併多個commit

 1# 這個命令,將最近4個commit合併爲1個,HEAD代表當前版本。
 2# 將進入VIM界面,你可以修改提交信息。
 3git rebase -i HEAD~4 
 4# 可以看到其中分爲兩個部分,上方未註釋的部分是填寫要執行的指令,
 5# 而下方註釋的部分則是指令的提示說明。指令部分中由前方的命令名稱、commit hash 和 commit message 組成
 6# 當前我們只要知道 pick 和 squash 這兩個命令即可。
 7# --> pick 的意思是要會執行這個 commit
 8# --> squash 的意思是這個 commit 會被合併到前一個commit
 9
10# 我們將 需要保留的 這個 commit 前方的命令改成 squash 或 s,然後輸入:wq以保存並退出
11# 這是我們會看到 commit message 的編輯界面
12
13# 其中, 非註釋部分就是兩次的 commit message, 你要做的就是將這兩個修改成新的 commit message。
14# 
15# 輸入wq保存並推出, 再次輸入git log查看 commit 歷史信息,你會發現這兩個 commit 已經合併了。
16# 將修改強制推送到前端
17git push -f origin master

修改遠程Commit記錄

 1git commit --amend
 2# amend只能修改沒有提交到線上的,最後一次commit記錄
 3git rebase -i HEAD~3
 4# 表示要修改當前版本的倒數第三次狀態
 5# 將要更改的記錄行首單詞 pick 改爲 edit
 6pick 96dc3f9 doc: Update quick-start.md
 7pick f1cce8a test(Transition):Add transition test (#47)
 8pick 6293516 feat(Divider): Add Divider component.
 9# Rebase eeb03a4..6293516 onto eeb03a4 (3 commands)
10#
11# Commands:
12# p, pick = use commit
13# r, reword = use commit, but edit the commit message
14# e, edit = use commit, but stop for amending
15# s, squash = use commit, but meld into previous commit
16# f, fixup = like "squash", but discard this commit's log message
17# x, exec = run command (the rest of the line) using shell
18# d, drop = remove commit

保存並退出,會彈出下面提示

 1# You can amend the commit now, with
 2# 
 3#   git commit --amend
 4# 
 5# Once you are satisfied with your changes, run
 6# 
 7#   git rebase --continue
 8
 9# 通過這條命令進入編輯頁面更改commit,保存退出
10git commit --amend
11# 保存退出確認修改,繼續執行 rebase, 
12git rebase --continue
13# 如果修改多條記錄反覆執行上面兩條命令直到完成所有修改
14
15# 最後,確保別人沒有提交進行push,最好不要加 -f 強制推送
16git push -f origin master

添加忽略文件

1echo node_modules/ >> .gitignore

利用commit關閉一個issue

這個功能在Github上可以玩兒,Gitlab上特別老的版本不能玩兒哦,那麼如何跟隨着commit關閉一個issue呢? 在confirm merge的時候可以使用一下命令來關閉相關issue:

fixes #xxxfixed #xxxfix #xxxcloses #xxxclose #xxxclosed #xxx

同步fork的上游倉庫

Github教程同步fork教程在Github上同步一個分支(fork)

設置添加多個遠程倉庫地址。

在同步之前,需要創建一個遠程點指向上游倉庫(repo).如果你已經派生了一個原始倉庫,可以按照如下方法做。

 1$ git remote -v
 2# List the current remotes (列出當前遠程倉庫)
 3# origin  https://github.com/user/repo.git (fetch)
 4# origin  https://github.com/user/repo.git (push)
 5$ git remote add upstream https://github.com/otheruser/repo.git
 6# Set a new remote (設置一個新的遠程倉庫)
 7$ git remote -v
 8# Verify new remote (驗證新的原唱倉庫)
 9# origin    https://github.com/user/repo.git (fetch)
10# origin    https://github.com/user/repo.git (push)
11# upstream  https://github.com/otheruser/repo.git (fetch)
12# upstream  https://github.com/otheruser/repo.git (push)

同步更新倉庫內容

同步上游倉庫到你的倉庫需要執行兩步:首先你需要從遠程拉去,之後你需要合併你希望的分支到你的本地副本分支。從上游的存儲庫中提取分支以及各自的提交內容。 master 將被存儲在本地分支機構 upstream/master

1git fetch upstream
2# remote: Counting objects: 75, done.
3# remote: Compressing objects: 100% (53/53), done.
4# remote: Total 62 (delta 27), reused 44 (delta 9)
5# Unpacking objects: 100% (62/62), done.
6# From https://github.com/ORIGINAL_OWNER/ORIGINAL_REPOSITORY
7#  * [new branch]      master     -> upstream/master

檢查你的 fork's 本地 master 分支

1git checkout master
2# Switched to branch 'master'

合併來自 upstream/master 的更改到本地 master 分支上。 這使你的前 fork's master 分支與上游資源庫同步,而不會丟失你本地修改。

1git merge upstream/master
2# Updating a422352..5fdff0f
3# Fast-forward
4#  README                    |    9 -------
5#  README.md                 |    7 ++++++
6#  2 files changed, 7 insertions(+), 9 deletions(-)
7#  delete mode 100644 README
8#  create mode 100644 README.md

批量修改歷史commit中的名字和郵箱

1.克隆倉庫

注意參數,這個不是普通的clone,clone下來的倉庫並不能參與開發

1git clone --bare https://github.com/user/repo.git
2cd repo.git

2.命令行中運行代碼

OLD_EMAIL原來的郵箱
CORRECT_NAME更正的名字
CORRECT_EMAIL更正的郵箱

將下面代碼複製放到命令行中執行

 1git filter-branch -f --env-filter '
 2OLD_EMAIL="[email protected]"
 3CORRECT_NAME="小弟調調"
 4CORRECT_EMAIL="更正的郵箱@qq.com"
 5if [ "$GIT_COMMITTER_EMAIL" = "$OLD_EMAIL" ]
 6then
 7    export GIT_COMMITTER_NAME="$CORRECT_NAME"
 8    export GIT_COMMITTER_EMAIL="$CORRECT_EMAIL"
 9fi
10if [ "$GIT_AUTHOR_EMAIL" = "$OLD_EMAIL" ]
11then
12    export GIT_AUTHOR_NAME="$CORRECT_NAME"
13    export GIT_AUTHOR_EMAIL="$CORRECT_EMAIL"
14fi
15' --tag-name-filter cat -- --branches --tags

執行過程

1Rewrite 160d4df2689ff6df3820563bfd13b5f1fb9ba832 (479/508) (16 seconds passed, remaining 0 predicted)
2Ref 'refs/heads/dev' was rewritten
3Ref 'refs/heads/master' was rewritten

3.同步到遠程倉庫

同步到push遠程git倉庫

1git push --force --tags origin 'refs/heads/*'

我還遇到了如下面錯誤,lab默認給master分支加了保護,不允許強制覆蓋。Project(項目)->Setting->Repository 菜單下面的Protected branches把master的保護去掉就可以了。修改完之後,建議把master的保護再加回來,畢竟強推不是件好事。

1remote: GitLab: You are not allowed to force push code to a protected branch on this project.

當上面的push 不上去的時候,先 git pull 確保最新代碼

1git pull  --allow-unrelated-histories
2# 或者指定分枝
3git pull origin master --allow-unrelated-histories

查看某個文件歷史

1git log --pretty=oneline 文件名  # 列出文件的所有改動歷史  
2git show c178bf49   # 某次的改動的修改記錄  
3git log -p c178bf49 # 某次的改動的修改記錄  
4git blame 文件名     # 顯示文件的每一行是在那個版本最後修改。  
5git whatchanged 文件名  # 顯示某個文件的每個版本提交信息:提交日期,提交人員,版本號,提交備註(沒有修改細節)  

打造自己的git命令

1git config --global alias.st status
2git config --global alias.br branch
3git config --global alias.co checkout
4git config --global alias.ci commit

配置好後再輸入git命令的時候就不用再輸入一大段了,例如我們要查看狀態,只需:

1git st

中文亂碼的解決方案

1git config --global core.quotepath false

新建倉庫

init

git init #初始化

status

git status #獲取狀態

add

git add file # .或*代表全部添加
git rm --cached <added_file_to_undo> # 在commit之前撤銷git add操作
git reset head # 好像比上面git rm --cached更方便

commit

git commit -m "message" #此處注意亂碼

remote

git remote add origin [email protected]:JSLite/test.git #添加源

push

1git push -u origin master # push同事設置默認跟蹤分支  
2git push origin master  
3git push -f origin master # 強制推送文件,縮寫 -f(全寫--force)

clone

git clone git://github.com/JSLite/JSLite.js.git
git clone git://github.com/JSLite/JSLite.js.git mypro #克隆到自定義文件夾
git clone [user@]example.com:path/to/repo.git/ #SSH協議還有另一種寫法。

git clone支持多種協議,除了HTTP(s)以外,還支持SSH、Git、本地文件協議等,下面是一些例子。git clone <版本庫的網址> <本地目錄名>

1git clone http[s]://example.com/path/to/repo.git/
2git clone ssh://example.com/path/to/repo.git/
3git clone git://example.com/path/to/repo.git/
4git clone /opt/git/project.git 
5git clone file:///opt/git/project.git
6git clone ftp[s]://example.com/path/to/repo.git/
7git clone rsync://example.com/path/to/repo.git/

本地

help

1git help config # 獲取幫助信息  

add

1git add *   # 跟蹤新文件   
2git add -u [path]   # 添加[指定路徑下]已跟蹤文件   

rm

1rm *&git rm *          # 移除文件  
2git rm -f *            # 移除文件  
3git rm --cached *      # 取消跟蹤  
4git mv file_from file_to  # 重命名跟蹤文件  
5git log   # 查看提交記錄  

commit

1git commit #提交更新   
2git commit -m 'message' #提交說明   
3git commit -a #跳過使用暫存區域,把所有已經跟蹤過的文件暫存起來一併提交   
4git commit --amend #修改最後一次提交   
5git commit log #查看所有提交,包括沒有push的commit    
6git commit -m "#133" #關聯issue 任意位置帶上# 符號加上issue號碼  
7git commit -m "fix #133" commit關閉issue  
8git commit -m '概要描述'$'\n\n''1.詳細描述'$'\n''2.詳細描述' #提交簡要描述和詳細描述  

reset

1git reset HEAD *  # 取消已經暫存的文件   
2git reset --mixed HEAD * # 同上   
3git reset --soft HEAD *  # 重置到指定狀態,不會修改索引區和工作樹   
4git reset --hard HEAD *  # 重置到指定狀態,會修改索引區和工作樹   
5git reset -- files *     # 重置index區文件   

revert

1git revert HEAD   # 撤銷前一次操作   
2git revert HEAD~  # 撤銷前前一次操作   
3git revert commit # 撤銷指定操作   

checkout

1git checkout -- file  # 取消對文件的修改(從暫存區——覆蓋worktree file)  
2git checkout branch|tag|commit -- file_name  # 從倉庫取出file覆蓋當前分支   
3git checkout HEAD~1 [文件]  # 將會更新 working directory 去匹配某次 commit   
4git checkout -- .          # 從暫存區取出文件覆蓋工作區   
5git checkout -b gh-pages  0c304c9  # 這個表示 從當前分支 commit 哈希值爲 0c304c9 的節點,分一個新的分支gh-pages出來,並切換到 gh-pages   

diff

 1git diff file     # 查看指定文件的差異   
 2git diff --stat   # 查看簡單的diff結果   
 3git diff  # 比較Worktree和Index之間的差異   
 4git diff --cached   # 比較Index和HEAD之間的差異   
 5git diff HEAD       # 比較Worktree和HEAD之間的差異   
 6git diff branch     # 比較Worktree和branch之間的差異   
 7git diff branch1 branch2  # 比較兩次分支之間的差異   
 8git diff commit commit    # 比較兩次提交之間的差異   
 9git diff master..test   # 上面這條命令只顯示兩個分支間的差異  
10git diff master...test    # 你想找出‘master’,‘test’的共有 父分支和'test'分支之間的差異,你用3個‘.'來取代前面的兩個'.'  

stash

1git stash # 將工作區現場(已跟蹤文件)儲藏起來,等以後恢復後繼續工作。   
2git stash list  # 查看保存的工作現場   
3git stash apply # 恢復工作現場   
4git stash drop  # 刪除stash內容   
5git stash pop   # 恢復的同時直接刪除stash內容   
6git stash apply stash@{0} # 恢復指定的工作現場,當你保存了不只一份工作現場時。   

merge

1git merge --squash test # 合併壓縮,將test上的commit壓縮爲一條   

cherry-pick

1git cherry-pick commit    # 揀選合併,將commit合併到當前分支   
2git cherry-pick -n commit # 揀選多個提交,合併完後可以繼續揀選下一個提交   

rebase

1git rebase master   # 將master分之上超前的提交,變基到當前分支  
2git rebase --onto master 169a6  # 限制回滾範圍,rebase當前分支從169a6以後的提交  
3git rebase --interactive # 交互模式,修改commit   
4git rebase --continue    # 處理完衝突繼續合併   
5git rebase --skip        # 跳過   
6git rebase --abort       # 取消合併    

分支branch

刪除

1git push origin :branchName  # 刪除遠程分支  
2git push origin --delete new # 刪除遠程分支new   
3git branch -d branchName     # 刪除本地分支,強制刪除用-D  
4git branch -d test      # 刪除本地test分支   
5git branch -D test      # 強制刪除本地test分支   
6git remote prune origin # 遠程刪除了,本地還能看到遠程存在,這條命令刪除遠程不存在的分支

提交

1git push -u origin branchName # 提交分支到遠程origin主機中  

拉取

git fetch -p #拉取遠程分支時,自動清理 遠程分支已刪除,本地還存在的對應同名分支。

分支合併

1git merge branchName      # 合併分支 - 將分支branchName和當前所在分支合併   
2git merge origin/master   # 在本地分支上合併遠程分支。   
3git rebase origin/master  # 在本地分支上合併遠程分支。   
4git merge test            # 將test分支合併到當前分支   

重命名

git branch -m old new #重命名分支

查看

1git branch      # 列出本地分支   
2git branch -r   # 列出遠端分支   
3git branch -a   # 列出所有分支   
4git branch -v   # 查看各個分支最後一個提交對象的信息   
5git branch --merge      # 查看已經合併到當前分支的分支   
6git branch --no-merge   # 查看爲合併到當前分支的分支   
7git remote show origin  # 可以查看remote地址,遠程分支

新建

1git branch test # 新建test分支  
2git branch newBrach 3defc69 # 指定哈希3defc69,新建分支名字爲newBrach
3git checkout -b newBrach origin/master # 取回遠程主機的更新以後,在它的基礎上創建一個新的分支  
4git checkout -b newBrach 3defc69 # 以哈希值3defc69,新建 newBrach 分支,並切換到該分支

連接

1git branch --set-upstream dev origin/dev     # 將本地dev分支與遠程dev分支之間建立鏈接  
2git branch --set-upstream master origin/next # 手動建立追蹤關係  

分支切換

1git checkout test     # 切換到test分支   
2git checkout -b test  # 新建+切換到test分支   
3git checkout -b test dev # 基於dev新建test分支,並切換   

遠端

1git fetch <遠程主機名> <分支名>   # fetch取回所有分支(branch)的更新  
2git fetch origin remotebranch[:localbranch]   #  從遠端拉去分支[到本地指定分支]   
3git merge origin/branch   # 合併遠端上指定分支   
4git pull origin remotebranch:localbranch  #  拉去遠端分支到本地分支   
5git push origin branch    # 將當前分支,推送到遠端上指定分支   
6git push origin localbranch:remotebranch  # 推送本地指定分支,到遠端上指定分支   
7git push origin :remotebranch   # 刪除遠端指定分支   
8git checkout -b [--track] test origin/dev # 基於遠端dev分支,新建本地test分支[同時設置跟蹤]  

submodule

克隆項目同時克隆submodule

1git clone https://github.com/jaywcjlove/handbook.git --depth=1 --recurse-submodules

克隆項目,之後再手動克隆 submodule 子項目

1git submodule add --force '倉庫地址' '路徑'
2# 其中,倉庫地址是指子模塊倉庫地址,路徑指將子模塊放置在當前工程下的路徑。
3# 注意:路徑不能以 / 結尾(會造成修改不生效)、不能是現有工程已有的目錄(不能順利 Clone)
4git submodule init # 初始化submodule
5git submodule update # 更新submodule(必須在根目錄執行命令)
6git submodule update --init --recursive  # 下載的工程帶有submodule

當使用git clone下來的工程中帶有submodule時,初始的時候,submodule的內容並不會自動下載下來的,此時,只需執行如下命令:

1git submodule foreach git pull  # submodule 裏有其他的 submodule 一次更新
2git submodule foreach git pull origin master # submodule更新
3
4git submodule foreach --recursive git submodule init
5git submodule foreach --recursive git submodule update

刪除文件

1git rm -rf node_modules/

remote

git是一個分佈式代碼管理工具,所以可以支持多個倉庫,在git裏,服務器上的倉庫在本地稱之爲remote。個人開發時,多源用的可能不多,但多源其實非常有用。

1git remote add origin1 [email protected]:yanhaijing/data.js.git  
2git remote    # 顯示全部源  
3git remote -v # 顯示全部源+詳細信息  
4git remote rename origin1 origin2 # 重命名  
5git remote rm origin    # 刪除  
6git remote show origin  # 查看指定源的全部信息  

標籤tag

當開發到一定階段時,給程序打標籤是非常棒的功能。

 1git tag -a v0.1 -m 'my version 1.4' # 新建帶註釋標籤   
 2git push origin --tags              # 一次性推送所有分支 
 3git push origin v1.5                # 推送單個tag到orgin源上 
 4git tag -v v1.4.2.1                 # 驗證標籤,驗證已經簽署的標籤
 5git show v1.5                       # 看到對應的 GPG 籤
 6
 7git tag        # 列出現有標籤   
 8git tag v0gi.1 # 新建標籤   
 9git checkout tagname   # 切換到標籤       
10git tag -d v0.1 # 刪除標籤   
11git push origin :refs/tags/v0.1 # 刪除遠程標籤   
12git pull --all # 獲取遠程所有內容包括tag  
13git --git-dir='<絕對地址>/.git' describe --tags HEAD # 查看本地版本信息  

日誌log

 1git config format.pretty oneline  #顯示歷史記錄時,每個提交的信息只顯示一行   
 2git config color.ui true #彩色的 git 輸出   
 3git log #查看提交日誌,從最近的提交開始顯示  
 4git log --reverse #查看提交日誌,從最遠的提交開始顯示
 5git log --pretty=oneline #單行顯示提交日誌   
 6git log --graph --pretty=oneline --abbrev-commit   
 7git log -num #顯示第幾條log(倒數)   
 8git reflog #查看所有分支的所有操作記錄   
 9git log --since=1.day #一天內的提交;你可以給出各種時間格式,比如說具體的某一天(“2008-01-15”),或者是多久以前(“2 years 1 day 3 minutes ago”)。   
10git log --pretty="%h - %s" --author=自己的名字 #查看自己的日誌   
11git log -p -2 #展開兩次更新顯示每次提交的內容差異   
12git log --stat #要快速瀏覽其他協作者提交的更新都作了哪些改動   
13git log --pretty=format:"%h - %an, %ar : %s"#定製要顯示的記錄格式   
14git log --pretty=format:'%h : %s' --date-order --graph # 拓撲順序展示   
15git log --pretty=format:'%h : %s - %ad' --date=short #日期YYYY-MM-DD顯示   
16git log <last tag> HEAD --pretty=format:%s # 只顯示commit   
17git config --global format.pretty '%h : %s - %ad' --date=short #日期YYYY-MM-DD顯示 寫入全局配置
選項 說明 選項 說明
%H 提交對象(commit)的完整哈希字串 %ad 作者修訂日期(可以用 -date= 選項定製格式)
%h 提交對象的簡短哈希字串 %ar 作者修訂日期,按多久以前的方式顯示
%T 樹對象(tree)的完整哈希字串 %cn 提交者(committer)的名字
%t 樹對象的簡短哈希字串 %ce 提交者的電子郵件地址
%P 父對象(parent)的完整哈希字串 %cd 提交日期
%p 父對象的簡短哈希字串 %cr 提交日期,按多久以前的方式顯示
%an 作者(author)的名字 %s 提交說明
%ae 作者的電子郵件地址 - -

Pretty Formats

重寫歷史

1git commit --amend    # 改變最近一次提交  
2git rebase -i HEAD~3  # 修改最近三次的提交說明,或者其中任意一次  
3git commit --amend    # 保存好了,這些指示很明確地告訴了你該幹什麼  
4git rebase --continue # 修改提交說明,退出編輯器。  
1pick f7f3f6d changed my name a bit
2pick 310154e updated README formatting and added blame
3pick a5f4a0d added cat-file

改成

1pick 310154e updated README formatting and added blame
2pick f7f3f6d changed my name a bit

刪除倉庫

1cd ..
2rm -rf repo.git

Github官方教程

其它

1git help *  # 獲取命令的幫助信息  
2git status  # 獲取當前的狀態,非常有用,因爲git會提示接下來的能做的操作  

報錯問題解決

1. git fatal: protocol error: bad line length character: No s

解決辦法:更換remote地址爲 http/https

2. The requested URL returned error: 403 Forbidden while accessing

解決github push錯誤的辦法:

 1#vim 編輯器打開 當前項目中的config文件
 2vim .git/config
 3
 4#修改
 5[remote "origin"]  
 6    url = https://github.com/jaywcjlove/example.git  
 7
 8#爲下面代碼
 9[remote "origin"]  
10    url = https://[email protected]/jaywcjlove/example.git  

3. git status 顯示中文問題

在查看狀態的時候 git status 如果是中文就顯示下面的情況

1\344\272\247\345\223\201\351\234\200\346\261\202

解決這個問題方法是:

1git config --global core.quotepath false

參考資料

最後修改於: Wednesday, January 31, 2024

相關文章:

翻譯: