Git 基礎(chǔ)
基本原理
- 客戶端并不是只提取最新版本的文件快照,而是把代碼倉庫完整的鏡像下來。這樣一來,任何一處協(xié)同工作用的服務(wù)器發(fā)生故障,事后都可以用任何一個鏡像出來的本地倉庫恢復(fù)。每一次的克隆操作,實際上都是一次對代碼倉庫的完整備份。
Git的優(yōu)勢
直接記錄快照
Git 更像是把數(shù)據(jù)看作是對小型文件系統(tǒng)的一組快照。 每次你提交更新,或在 Git 中保存項目狀態(tài)時,它主要對當(dāng)時的全部文件制作一個快照并保存這個快照的索引。 為了高效,如果文件沒有修改,Git 不再重新存儲該文件,而是只保留一個鏈接指向之前存儲的文件。 Git 對待數(shù)據(jù)更像是一個 快照流。
如圖,在version2中的 B 即是因為 File B 沒有改變,所以直接存儲了一個指向 FileB 的鏈接。只有修改了的文件才會產(chǎn)生一個新的文件,覆蓋原來的文件。

幾乎所有操作都在本地執(zhí)行
- 在 Git 中的絕大多數(shù)操作都只需要訪問本地文件和資源,一般不需要來自網(wǎng)絡(luò)上其它計算機的信息。因為你在本地磁盤上就有項目的完整歷史,所以大部分操作看起來瞬間完成。
Git保證完整性
- Git 中所有數(shù)據(jù)在存儲前都計算校驗和,然后以校驗和來引用。Git 用以計算校驗和的機制叫做 SHA-1 散列(hash,哈希)。Git 數(shù)據(jù)庫中保存的信息都是以文件內(nèi)容的哈希值來確定的,而不是文件名。
- 這意味著不可能在 Git 不知情時更改任何文件內(nèi)容或目錄內(nèi)容。 這個功能建構(gòu)在 Git 底層,是構(gòu)成 Git 哲學(xué)不可或缺的部分。 若你在傳送過程中丟失信息或損壞文件,Git 就能發(fā)現(xiàn)。
Git一般只添加數(shù)據(jù)
- 你執(zhí)行的 Git 操作,幾乎只往 Git 數(shù)據(jù)庫中增加數(shù)據(jù)。 很難讓 Git 執(zhí)行任何不可逆操作,或者讓它以任何方式清除數(shù)據(jù)。 同別的 VCS 一樣,未提交更新時有可能丟失或弄亂修改的內(nèi)容;但是一旦你提交快照到 Git 中,就難以再丟失數(shù)據(jù),特別是如果你定期的推送數(shù)據(jù)庫到其它倉庫的話。這個特性使得我們可以盡情的嘗試對Git進行操作而不用害怕把它改壞了,只需要回滾即可。
需要注意的重點
三種狀態(tài)
已提交 committed :數(shù)據(jù)已經(jīng)保存在本地 Git 倉庫
已修改 modified : 修改了文件,但是還沒保存在倉庫中
已暫存 staged : 對一個已修改的文件的當(dāng)前版本做了標(biāo)記

三個區(qū)域
- 工作目錄 Working Directory :對項目的某個版本獨立提取出來的內(nèi)容,這些從Git倉庫的壓縮數(shù)據(jù)庫提取出來的文件,放在磁盤上供你使用或修改。
- 暫存區(qū)域 Staging Area :是一個文件,保存了下次將提交的文件列表,是待提交文件的暫存區(qū)域。一般在Git倉庫的目錄中,有時也被稱為索引。
- Git倉庫:用來保存項目的元數(shù)據(jù)和對象數(shù)據(jù)庫的地方。是Git中最重要的部分,從其他計算機克隆倉庫時拷貝的就是這里的數(shù)據(jù)
基本的Git工作流程
- 在工作目錄中修改文件
- 暫存文件,將文件的快照存儲在暫存區(qū)域
- 提交更新,找到暫存區(qū)域的位置,將快照永久性存儲到Git倉庫目錄
- 提交狀態(tài):如果Git目錄中保存著特定版本的文件,就屬于已提交狀態(tài)。
- 暫存狀態(tài):如果做了修改并且已經(jīng)放入暫存區(qū)域,就屬于暫存狀態(tài)。
- 已修改狀態(tài):如果自上次取出后,做了修改但是還沒有存在暫存區(qū)域,就是已修改狀態(tài)。
基本的Git操作流程
基礎(chǔ)設(shè)置
-
首先最基礎(chǔ)的是需要配置用戶信息
$ git config --global user.name "lanya" $ git config --global user.email shenglanya@corp.netease.com關(guān)于 config 的種類
Config file location # global 表示配置全局信息,配置之后無論你在該系統(tǒng)上做任何事情,Git都會使用這些信息。 --global use global config file --system use system config file --local use repository config file -f, --file <file> use given config file --blob <blob-id> read config from given blob object -
接著需要檢查你的配置信息,使用
$ git config --list指令檢查全部配置信息,結(jié)果如下:core.excludesfile=~/.gitignore core.legacyheaders=false core.quotepath=false mergetool.keepbackup=true push.default=simple color.ui=auto color.interactive=auto repack.usedeltabaseoffset=true alias.s=status alias.a=!git add . && git status alias.au=!git add -u . && git status alias.aa=!git add . && git add -u . && git status alias.c=commit alias.cm=commit -m alias.ca=commit --amend alias.ac=!git add . && git commit alias.acm=!git add . && git commit -m alias.l=log --graph --all --pretty=format:'%C(yellow)%h%C(cyan)%d%Creset %s %C(white)- %an, %ar%Creset' alias.ll=log --stat --abbrev-commit alias.lg=log --color --graph --pretty=format:'%C(bold white)%h%Creset -%C(bold green)%d%Creset %s %C(bold green)(%cr)%Creset %C(bold blue)<%an>%Creset' --abbrev-commit --date=relative alias.llg=log --color --graph --pretty=format:'%C(bold white)%H %d%Creset%n%s%n%+b%C(bold blue)%an <%ae>%Creset %C(bold green)%cr (%ci)' --abbrev-commit alias.d=diff alias.master=checkout master alias.spull=svn rebase alias.spush=svn dcommit alias.alias=!git config --list | grep 'alias\.' | sed 's/alias\.\([^=]*\)=\(.*\)/\1\ => \2/' | sort include.path=~/.gitcinclude include.path=.githubconfig include.path=.gitcredential diff.exif.textconv=exif credential.helper=osxkeychain core.excludesfile=/Users/shenglanya/.gitignore_global difftool.sourcetree.cmd=opendiff "$LOCAL" "$REMOTE" difftool.sourcetree.path= mergetool.sourcetree.cmd=/Applications/Sourcetree.app/Contents/Resources/opendiff-w.sh "$LOCAL" "$REMOTE" -ancestor "$BASE" -merge "$MERGED" mergetool.sourcetree.trustexitcode=true user.name=shenglanya user.email=shenglanya@corp.netease.com commit.template=/Users/shenglanya/.stCommitMsg core.repositoryformatversion=0 core.filemode=true core.bare=false core.logallrefupdates=true core.ignorecase=true core.precomposeunicode=true remote.origin.url=https://git.ms.netease.com/netease-precious-metals-client/ios-client.git remote.origin.fetch=+refs/heads/*:refs/remotes/origin/* branch.essential.remote=origin branch.essential.merge=refs/heads/essential branch.r_4.4.remote=origin branch.r_4.4.merge=refs/heads/r_4.4 -
使用
$ git config <key>來檢查某一項配置信息$ git config user.name shenglanya
查閱幫助手冊方法
-
以下方法均可找到 Git 命令手冊
$ git help <verb> $ git <verb> --help $ man git-<verb>
獲取Git倉庫
方法一:在現(xiàn)有目錄中初始化倉庫(創(chuàng)建一個新的自己的倉庫)
git init該命令將創(chuàng)建一個名為.git的子目錄,這個子目錄含有你在初始化的Git倉庫中所有的必須文件,這些文件是Git倉庫的骨干。但是,在這個時候,我們僅僅是做了一個初始化的操作,你的項目里的文件還沒有被跟蹤。-
如果你是在一個已經(jīng)存在文件的文件夾(而不是空文件夾)中初始化 Git 倉庫來進行版本控制的話,你應(yīng)該開始跟蹤這些文件并提交。 你可通過
git add命令來實現(xiàn)對指定文件的跟蹤,然后執(zhí)行git commit提交:$ git add *.c $ git add LICENSE $ git commit -m 'initial project version' -
具體操作流程
# 首先 $ git init Initialized empty Git repository in /Users/shenglanya/Desktop/.git/ #然后使用 ls -a 可查看隱藏文件,發(fā)現(xiàn)存在名為 .git 的子目錄 $ ls -a . .DS_Store .localized .. .git pic # 接著進入子目錄,發(fā)現(xiàn)此目錄中包含你初始化倉庫中所有的必須文件,這些文件是 Git 倉庫的骨干 $ cd .git $ ls HEAD config hooks objects branches description info refs # 接著需要跟蹤項目里的文件,需要注意的是,當(dāng)創(chuàng)建一個新的項目里的文件時,它默認(rèn)是未被跟蹤的,所以此時我們需要手動的將它添加到版本控制中,也就是被跟蹤
方法二:克隆現(xiàn)有倉庫(clone別人的)
-
如果你想獲得一份已經(jīng)存在了的 Git 倉庫的拷貝,比如說,你想為某個開源項目貢獻自己的一份力,這時就要用到
git clone命令。Git 克隆的是該 Git 倉庫服務(wù)器上的幾乎所有數(shù)據(jù),而不是僅僅復(fù)制完成你的工作所需要文件。 當(dāng)你執(zhí)行git clone命令的時候,默認(rèn)配置下遠(yuǎn)程 Git 倉庫中的每一個文件的每一個版本都將被拉取下來。$ git clone https://github.com/libgit2/libgit2Git 支持多種數(shù)據(jù)傳輸協(xié)議。 上面的例子使用的是
https://協(xié)議,不過你也可以使用git://協(xié)議或者使用 SSH 傳輸協(xié)議,比如user@server:path/to/repo.git。
記錄每次更新到倉庫
- 你工作目錄下的每一個文件都不外乎這兩種狀態(tài):已跟蹤或未跟蹤。 已跟蹤的文件是指那些被納入了版本控制的文件,在上一次快照中有它們的記錄,在工作一段時間后,它們的狀態(tài)可能處于未修改,已修改或已放入暫存區(qū)。 工作目錄中除已跟蹤文件以外的所有其它文件都屬于未跟蹤文件,它們既不存在于上次快照的記錄中,也沒有放入暫存區(qū)。 初次克隆某個倉庫的時候,工作目錄中的所有文件都屬于已跟蹤文件,并處于未修改狀態(tài)。
檢查當(dāng)前文件狀態(tài)
-
要查看哪些文件處于什么狀態(tài),可以用
git status命令。 如果在克隆倉庫后立即使用此命令,會看到類似這樣的輸出:$ git status On branch master nothing to commit, working directory clean這說明你現(xiàn)在的工作目錄相當(dāng)干凈。表示所有已跟蹤文件在上次提交后都未被更改過。 此外,上面的信息還表明,當(dāng)前目錄下沒有出現(xiàn)任何處于未跟蹤狀態(tài)的新文件,否則 Git 會在這里列出來。 最后,該命令還顯示了當(dāng)前所在分支,并告訴你這個分支同遠(yuǎn)程服務(wù)器上對應(yīng)的分支沒有偏離。 現(xiàn)在,分支名是 “master”,這是默認(rèn)的分支名。
-
如果你在當(dāng)前已經(jīng)有倉庫管理的項目中添加了一個文件,名字叫做 README 。然后使用
git status命令,你會發(fā)現(xiàn)會出現(xiàn):$ echo 'My Project' > README $ git status On branch master Untracked files: (use "git add <file>..." to include in what will be committed) README nothing added to commit but untracked files present (use "git add" to track)表示 README 還未被跟蹤,表示 Git 之前的提交中沒有這些文件。Git也不會自動跟蹤它,這使得你不必?fù)?dān)心將生成的二進制文件或者其他不想被包含的文件包含進來。若你想跟蹤它,則需要明明白白的告訴它你想跟蹤這個文件,使用
git add指令。
跟蹤新文件
-
使用
git add可以跟蹤新文件。所以可以使用git add README, 然后再運行git status會看到$ git status On branch master No commits yet Changes to be committed: (use "git rm --cached <file>..." to unstage) new file: pic/git存儲項目雖時間改變的快照.png new file: pic/lifecycle.png new file: pic/工作目錄,暫存區(qū)域及Git倉庫.png Untracked files: (use "git add <file>..." to include in what will be committed) pic/實習(xí)學(xué)習(xí)筆記.md # 使用 git add 后 $ git add pic/實習(xí)學(xué)習(xí)筆記.md $ git status On branch master No commits yet Changes to be committed: (use "git rm --cached <file>..." to unstage) new file: pic/git存儲項目雖時間改變的快照.png new file: pic/lifecycle.png new file: pic/實習(xí)學(xué)習(xí)筆記.md new file: pic/工作目錄,暫存區(qū)域及Git倉庫.png只要在
Changes to be committed這行下面的,就說明是已暫存狀態(tài)。 如果此時提交,那么該文件此時此刻的版本將被留存在歷史記錄中。 你可能會想起之前我們使用git init后就運行了git add (files)命令,開始跟蹤當(dāng)前目錄下的文件。git add命令使用文件或目錄的路徑作為參數(shù);如果參數(shù)是目錄的路徑,該命令將遞歸地跟蹤該目錄下的所有文件。 -
關(guān)于
git add指令還有別的作用:- 用于追蹤新文件
- 用于將已跟蹤的文件放入暫存區(qū)
- 用于合并時把有沖突的文件標(biāo)記為已解決
暫存已修改文件
-
修改已被跟蹤的文件。比如說修改了一個名為 實習(xí)學(xué)習(xí)筆記.md 的文件,然后運行
git status$ git status On branch master No commits yet Changes to be committed: (use "git rm --cached <file>..." to unstage) new file: pic/git存儲項目雖時間改變的快照.png new file: pic/lifecycle.png new file: pic/實習(xí)學(xué)習(xí)筆記.md new file: pic/工作目錄,暫存區(qū)域及Git倉庫.png # 說明已跟蹤文件內(nèi)容發(fā)生了變化,但是還未放入暫存區(qū)。如果想暫存這次更新,需要使用 git add 指令。 git add 指令是一個多功能命令:可以用它來跟蹤新文件,或者把已經(jīng)跟蹤的文件放到暫存區(qū)中,還能用于合并時把有沖突的文件標(biāo)記為已解決狀態(tài)等。 Changes not staged for commit: (use "git add <file>..." to update what will be committed) (use "git checkout -- <file>..." to discard changes in working directory) modified: pic/實習(xí)學(xué)習(xí)筆記.md # 使用 git add 指令將其添加到暫存區(qū) $ git add pic/實習(xí)學(xué)習(xí)筆記.md $ git status On branch master No commits yet Changes to be committed: (use "git rm --cached <file>..." to unstage) new file: pic/git存儲項目雖時間改變的快照.png new file: pic/lifecycle.png new file: pic/實習(xí)學(xué)習(xí)筆記.md new file: pic/工作目錄,暫存區(qū)域及Git倉庫.png
- 需要注意的是,當(dāng)已經(jīng)使用了
git add指令暫存的版本又經(jīng)過修改之后,需在再重新使用git add指令將最新的修改放入暫存區(qū),否則此時暫存區(qū)里只有上一次修改的內(nèi)容。
提交文件到倉庫
-
使用
git commit指令可以使得暫存在暫存區(qū)的文件被提交到倉庫中去。$ git commit [master (root-commit) 2713657] 第一次的修改提交 4 files changed, 22 insertions(+) create mode 100644 pic/git存儲項目雖時間改變的快照.png create mode 100644 pic/lifecycle.png create mode 100644 pic/實習(xí)學(xué)習(xí)筆記.md create mode 100644 pic/工作目錄,暫存區(qū)域及Git倉庫.png
基本的 Git 操作指令
git status 命令概述
-
使用
git status時,實際上可以使用更為方便的指令來達到更為緊湊的格式輸出。比如使用git status -s$ git status -s # M 靠右的 M 表示修改過的文件并且還未被放入暫存區(qū) M README # MM 靠左的 M 表示該文件被修改后放入了暫存區(qū),靠右的表示修改過的文件并且還未被放入暫存區(qū),所以 Rakefile 文件被修改過后放入了暫存區(qū),但是之后又進行了修改,還未將最后一次修改放入暫存區(qū) MM Rakefile # A 表示新添加到暫存區(qū)的文件 A lib/git.rb # M 靠左的 M 表示該文件被修改后放入了暫存區(qū) M lib/simplegit.rb # ?? 表示還未被跟蹤 ?? LICENSE.txt # 所以此時暫存區(qū)中的文件有 Rakefile, lib/git.rb, lib/simplegit.rb
git diff 命令概述
-
git diff可以說是git status的具體版本,git status只能查看修改了哪些文件,而git diff能夠具體到該文件的某一部分。通常有以下兩個用法-
當(dāng)前做的更新哪些還沒有暫存?
首先修改 pic/實習(xí)學(xué)習(xí)筆記.md 文件,然后使用 git status 指令
$ git status On branch master Changes not staged for commit: (use "git add <file>..." to update what will be committed) (use "git checkout -- <file>..." to discard changes in working directory) modified: pic/實習(xí)學(xué)習(xí)筆記.md # 表示該文件修改后還沒有暫存此時使用
git diff可以查看當(dāng)前未暫存文件更新了哪些部分$ git diff diff --git a/pic/實習(xí)學(xué)習(xí)筆記.md b/pic/實習(xí)學(xué)習(xí)筆記.md index 2b4e07b..a50f1a2 100644 --- a/pic/實習(xí)學(xué)習(xí)筆記.md +++ b/pic/實習(xí)學(xué)習(xí)筆記.md @@ -14,7 +14,7 @@ -* 有額外時間的話,需要將之前沒讀完的書繼續(xù)讀下去。 +* 有額外時間的話,需要將之前沒讀完的書繼續(xù)讀下去。呵呵呵此時就可以查看未暫存文件修改的部分了。
-
有哪些更新已經(jīng)暫存起來了準(zhǔn)備好了下次提交?
可以使用
git diff --staged指令查看,首先需要使用git add指令將剛剛修改的文件加入暫存區(qū)$ git add pic/實習(xí)學(xué)習(xí)筆記.md shenglanyadeMacBook-Pro:desktop shenglanya$ git diff --staged diff --git a/pic/實習(xí)學(xué)習(xí)筆記.md b/pic/實習(xí)學(xué)習(xí)筆記.md index 2b4e07b..a50f1a2 100644 --- a/pic/實習(xí)學(xué)習(xí)筆記.md +++ b/pic/實習(xí)學(xué)習(xí)筆記.md @@ -14,7 +14,7 @@ -* 有額外時間的話,需要將之前沒讀完的書繼續(xù)讀下去。 +* 有額外時間的話,需要將之前沒讀完的書繼續(xù)讀下去。呵呵呵
-
-
-
當(dāng)我們將文件暫存后繼續(xù)編輯時,使用
git status指令查看如下:$ git status On branch master Changes to be committed: (use "git reset HEAD <file>..." to unstage) modified: pic/實習(xí)學(xué)習(xí)筆記.md Changes not staged for commit: (use "git add <file>..." to update what will be committed) (use "git checkout -- <file>..." to discard changes in working directory) modified: pic/實習(xí)學(xué)習(xí)筆記.md # 該文件同時出現(xiàn)在了暫存區(qū)和修改部分。 -
現(xiàn)在運行
git diff查看暫存前后的變化git diff diff --git a/pic/實習(xí)學(xué)習(xí)筆記.md b/pic/實習(xí)學(xué)習(xí)筆記.md index a50f1a2..2b4e07b 100644 --- a/pic/實習(xí)學(xué)習(xí)筆記.md +++ b/pic/實習(xí)學(xué)習(xí)筆記.md @@ -14,7 +14,7 @@ -* 有額外時間的話,需要將之前沒讀完的書繼續(xù)讀下去。呵呵呵 +* 有額外時間的話,需要將之前沒讀完的書繼續(xù)讀下去。 -
再使用
git diff --staged查看變化$ git diff --staged diff --git a/pic/實習(xí)學(xué)習(xí)筆記.md b/pic/實習(xí)學(xué)習(xí)筆記.md index 2b4e07b..a50f1a2 100644 --- a/pic/實習(xí)學(xué)習(xí)筆記.md +++ b/pic/實習(xí)學(xué)習(xí)筆記.md @@ -14,7 +14,7 @@ -* 有額外時間的話,需要將之前沒讀完的書繼續(xù)讀下去。 +* 有額外時間的話,需要將之前沒讀完的書繼續(xù)讀下去。呵呵呵表示這個指令查看的是暫存區(qū)中文件的修改。
git commit 命令概述
當(dāng)使用
git commit命令提交暫存區(qū)域的文件時,一定要確認(rèn)是否還有什么修改過或新建的文件還未放入暫存區(qū),否則一旦提交,這些文件或修改都會只留在本地磁盤,不會加入版本控制中。所以每次提交前都需要執(zhí)行git status命令來查看是否都暫存起來了-
可以在 commit 命令后添加 -m 選項,將提交信息與命令放在同一行
$ git commit -m "Story 182: Fix benchmarks for speed" # 表示當(dāng)前在 master 分支上提交的,本次提交的完整 SHA-1 校驗和是 463dc4f [master 463dc4f] Story 182: Fix benchmarks for speed 2 files changed, 2 insertions(+) create mode 100644 README 注意:提交的是放在暫存區(qū)的快照,任何還未暫存的仍然保持已修改狀態(tài),可以在下次提交時再納入版本管理。每一次提交都是對項目的一次快照,以后可以回到這個狀態(tài)或進行比較。
使用
git commit -a可以跳過暫存這一步驟,git 會自動把所有已經(jīng)跟蹤過的文件暫存起來并且提交,即跳過git add步驟。
git rm 命令概述
要從 Git 中移除某個文件,就必須從已經(jīng)跟蹤的文件清單中刪除,然后提交。
-
刪除有兩種方式
- 第一種是簡單的從暫存區(qū)中刪除。但是文件還在被跟蹤著。
- 第二種是直接在未暫存區(qū)域中移除文件,表示直接將文件移除版本控制中。不再跟蹤。
-
下面來演示一下,首先對工作區(qū)域中的文件刪除,使用
rm pic/實習(xí)學(xué)習(xí)筆記.md$ rm pic/實習(xí)學(xué)習(xí)筆記.md $ git status On branch master Changes not staged for commit: (use "git add/rm <file>..." to update what will be committed) (use "git checkout -- <file>..." to discard changes in working directory) deleted: pic/實習(xí)學(xué)習(xí)筆記.md no changes added to commit (use "git add" and/or "git commit -a") # 此時將文件從暫存區(qū)域中刪除,但是文件還在被追蹤 -
然后再將文件從跟蹤中刪除,這里兩種指令
$ git rm pic/實習(xí)學(xué)習(xí)筆記.md和$ git add pic/實習(xí)學(xué)習(xí)筆記.md都能達到同樣效果。$ git add pic/實習(xí)學(xué)習(xí)筆記.md $ git status On branch master Changes to be committed: (use "git reset HEAD <file>..." to unstage) deleted: pic/實習(xí)學(xué)習(xí)筆記.md 需要注意的是,如果刪除文件之前文件修改過并且已經(jīng)放入了暫存區(qū)域,則必須使用強制刪除選項
-f才能將其刪除。主要是為了防止誤刪。-
當(dāng)我們想要將文件從 Git 倉庫中刪除但是卻想讓他仍在我們的工作區(qū)域中時,(即保存在本地磁盤并且不被 Git 跟蹤),為了達到這一目的,使用
--cached選項。$ git rm --cached pic/git存儲項目雖時間改變的快照.png rm 'pic/git存儲項目雖時間改變的快照.png' # 執(zhí)行完此命令后,pic/git存儲項目雖時間改變的快照.png 文件還在本地磁盤上,并沒有被刪除。
git mv 命令概述
Git 并不顯式的跟蹤文件移動操作。所以如果 Git 重命名某個文件,倉庫中存儲的元數(shù)據(jù)并不會體現(xiàn)出這是一次改名操作。
-
當(dāng)我們想在 Git 中對文件進行改名可以使用
git mv a b方式來操作$ git mv pic/實習(xí)學(xué)習(xí)筆記.md pic/note.md $ git diff --staged diff --git a/pic/實習(xí)學(xué)習(xí)筆記.md b/pic/note.md similarity index 100% rename from pic/實習(xí)學(xué)習(xí)筆記.md rename to pic/note.md -
git mv等價于$ mv pic/實習(xí)學(xué)習(xí)筆記.md pic/note.md $ git rm pic/實習(xí)學(xué)習(xí)筆記.md $ git add pic/note.md
忽略文件
-
我們有時會有些文件不需要 Git 來進行管理,也不希望他們總是出現(xiàn)在未跟蹤列表中,所以此時,我們可以創(chuàng)建一個名為 .gitignore 的文件,并在其中列出要忽略掉文件模式。
# 先創(chuàng)建此忽略文件并向其中添加需要忽略的文件 $ vi .gitignore # 查看此文件 $ cat .gitignore .localized # 表示忽略所有以 .o 或 .a 結(jié)尾的文件 *.[oa] # 表示忽略所有以波浪符(~)結(jié)尾的文件 *~ -
一些規(guī)范如下
- 所有空行或者以
#開頭的行都會被 Git 忽略。 - 可以使用標(biāo)準(zhǔn)的 glob 模式匹配。glob 即是指 shell 簡化了的正則表達式。
- 其中 * 可以匹配 0 ~ n 個字符
- ? 只能匹配一個字符
- [0-9]表示匹配所有 0 到 9 的數(shù)字
- ** 表示匹配任意中間目錄 比如
a/**/z可以匹配 a/z, a/b/z, a/b/c/z 等
- 匹配模式可以以(
/)開頭防止遞歸。 - 匹配模式可以以(
/)結(jié)尾指定目錄。 - 要忽略指定模式以外的文件或目錄,可以在模式前加上驚嘆號(
!)取反。
- 所有空行或者以
git stash 命令概述
當(dāng)我們已經(jīng)在一個分支上修改文件后,如果必須要切換到其他分支展開其他的工作,而當(dāng)前分支的工作還沒有完成,此時我們需要使用
$ git stash或$ git stash save命令將當(dāng)前分支上的工作暫存到棧上,這時你的工作目錄就干凈了,就可以切換到其他分支工作,等工作完成后,再切換回原來的分支,可以使用$ git stash apply將你剛剛的儲藏重新應(yīng)用。如果想查看你當(dāng)前一共有多少個儲藏,可以使用$ git stash list來查看。如果你并不想應(yīng)用最新的分支,而是想應(yīng)用某一個早些時間的分支,你可以使用$ git stash apply stash@{1},其中最后一個括號內(nèi)的數(shù)字為你某一次提交到工作棧上的暫存記錄。如果你不指定 apply 的參數(shù),git 將認(rèn)為你想要應(yīng)用最近一次的儲藏。當(dāng)我們返回原本的分支后,使用
$ git stash apply指令恢復(fù)了工作棧中暫存的數(shù)據(jù),但是如果當(dāng)你提交這個分支之前,已經(jīng)在暫存區(qū)緩存了一部分工作內(nèi)容,并且使用 stash 保存了工作狀態(tài),此時當(dāng)你恢復(fù)工作棧中的數(shù)據(jù)后,實際上暫存區(qū)中的內(nèi)容將會被移出暫存區(qū),而被放在了工作目錄中修改的部分,你需要手動將它再放回暫存區(qū),否則可以使用$ git stash apply --index來嘗試重新將暫存區(qū)的文件恢復(fù)到暫存區(qū)中。當(dāng)你把這個修改放入暫存區(qū)后,實際上堆棧上還有這個修改的記錄,此時你可以使用$ git stash drop stash@{1}來從棧中移除它,或者直接使用$ git stash pop來應(yīng)用儲藏棧這樣它就會自動從儲藏棧上消失了。-
$ git stash --keep-index指令的作用在于告訴 Git 不要儲藏任何你通過 git add 命令已經(jīng)暫存的東西,也就是說比如你現(xiàn)在已經(jīng)修改了一部分工作目錄中的內(nèi)容,并且還有一部分已經(jīng)被你暫存了下來。此時你暫時不想繼續(xù)改工作目錄中的內(nèi)容了,可是你也不想將它暫存到暫存區(qū),此時可以使用這個指令將它暫存到工作棧上。$ git status -s M index.html M lib/simplegit.rb $ git stash --keep-index Saved working directory and index state WIP on master: 1b65b17 added the index file HEAD is now at 1b65b17 added the index file $ git status -s M index.html $ git stash -u可以儲藏還未跟蹤的文件到工作棧-
$ git stash branch如果使用 stash 儲藏了一些工作,然后繼續(xù)在儲藏的分支上工作,在重新應(yīng)用 stash 儲藏的文件工作時可能會有問題。 如果應(yīng)用嘗試修改剛剛儲藏的修改的文件,也就是兩次同時修改了一個文件,你會得到一個合并沖突并不得不解決它。 如果想要一個輕松的方式來再次測試儲藏的改動,可以運行git stash branch創(chuàng)建一個新分支,檢出儲藏工作時所在的提交,重新在那應(yīng)用工作,然后在應(yīng)用成功后扔掉儲藏$ git stash branch testchanges Switched to a new branch "testchanges" # On branch testchanges # Changes to be committed: # (use "git reset HEAD <file>..." to unstage) # # modified: index.html # # Changed but not updated: # (use "git add <file>..." to update what will be committed) # # modified: lib/simplegit.rb # Dropped refs/stash@{0} (f0dfc4d5dc332d1cee34a634182e168c4efc3359) $ git stash -all可以移除工作目錄中所有未跟蹤的文件并且存儲在工作棧上,相應(yīng)的一個不怎么安全的方法是$ git clean直接清除了內(nèi)容,無法追溯回。不過可以使用git clean命令去除冗余文件或者清理工作目錄。 使用git clean -f -d命令來移除工作目錄中所有未追蹤的文件以及空的子目錄。-f意味著 強制 或 “確定移除”。在使用$ git clean之前,我們可以先使用$ git clean -d -n來看一下這樣做的后果是什么,也就是有什么文件會被移除。
git log 命令概述
-
在提交了若干更新,又或者克隆了某個項目之后,你也許想回顧下提交歷史。 此時便需要
git log命令。默認(rèn)不加其他參數(shù)時,git log惠安提交時間列出所有更新。$ git log commit fb40f7a259de8ec2f2edbada6f85aa855f4a6585 (HEAD -> master) Author: shenglanya <shenglanya@corp.netease.com> Date: Wed Mar 7 11:34:54 2018 +0800 add pic commit ec50914561593b769a98ff468de6697a6d964cbd Author: shenglanya <shenglanya@corp.netease.com> Date: Wed Mar 7 11:33:36 2018 +0800 xiugai commit a7372097ab8f063e17beca6fa8f82a15bb11c5e3 Author: shenglanya <shenglanya@corp.netease.com> Date: Wed Mar 7 11:20:05 2018 +0800 提交 -
常用選項
-p,用來顯示每次提交的內(nèi)容差異,可以加上 -2 來僅僅顯示最近兩次提交$ git log -p commit fb40f7a259de8ec2f2edbada6f85aa855f4a6585 (HEAD -> master) Author: shenglanya <shenglanya@corp.netease.com> Date: Wed Mar 7 11:34:54 2018 +0800 add pic diff --git a/pic/git存儲項目雖時間改變的快照.png b/pic/git存儲項目雖時間改變的快照.png new file mode 100644 index 0000000..1036a42 Binary files /dev/null and b/pic/git存儲項目雖時間改變的快照.png differ commit ec50914561593b769a98ff468de6697a6d964cbd Author: shenglanya <shenglanya@corp.netease.com> Date: Wed Mar 7 11:33:36 2018 +0800 xiugai diff --git a/pic/git存儲項目雖時間改變的快照.png b/pic/git存儲項目雖時間改變的快照.png deleted file mode 100644 index 1036a42..0000000 Binary files a/pic/git存儲項目雖時間改變的快照.png and /dev/null differ -
--stat選項可以看到每次提交的簡略統(tǒng)計信息$ git log --stat commit fb40f7a259de8ec2f2edbada6f85aa855f4a6585 (HEAD -> master) Author: shenglanya <shenglanya@corp.netease.com> Date: Wed Mar 7 11:34:54 2018 +0800 add pic pic/git存儲項目雖時間改變的快照.png | Bin 0 -> 20722 bytes 1 file changed, 0 insertions(+), 0 deletions(-) commit ec50914561593b769a98ff468de6697a6d964cbd Author: shenglanya <shenglanya@corp.netease.com> Date: Wed Mar 7 11:33:36 2018 +0800 xiugai pic/git存儲項目雖時間改變的快照.png | Bin 20722 -> 0 bytes pic/實習(xí)學(xué)習(xí)筆記.md | 22 ++++++++++++++++++++++ 2 files changed, 22 insertions(+) commit a7372097ab8f063e17beca6fa8f82a15bb11c5e3 Author: shenglanya <shenglanya@corp.netease.com> Date: Wed Mar 7 11:20:05 2018 +0800 -
常用選項
--pretty可以指定使用不同于默認(rèn)格式的方式展示提交信息。比如oneline將每個提交放在一行顯示,查看到提交數(shù)很大時非常有用。另外還有shortfull等。$ git log --pretty=oneline fb40f7a259de8ec2f2edbada6f85aa855f4a6585 (HEAD -> master) add pic ec50914561593b769a98ff468de6697a6d964cbd xiugai a7372097ab8f063e17beca6fa8f82a15bb11c5e3 提交 2713657f264a3a019580dc3a489d303fade5dc5c 第一次的修改提交 -
format選項可以定制要顯示的記錄格式。這樣的輸出對后期提取分析格外有用。$git log --pretty=format:"%h - %an, %ar : s" fb40f7a - shenglanya, 60 minutes ago : add pic ec50914 - shenglanya, 61 minutes ago : xiugai a737209 - shenglanya, 74 minutes ago : 提交 2713657 - shenglanya, 3 hours ago : 第一次的修改提交常用選項以及其代表意義
選項 說明 %H 提交對象(commit)的完整哈希字串 %h 提交對象的簡短哈希字串 %T 樹對象(tree)的完整哈希字串 %t 樹對象的簡短哈希字串 %P 父對象(parent)的完整哈希字串 %p 父對象的簡短哈希字串 %an 作者(author)的名字 %ae 作者的電子郵件地址 %ad 作者修訂日期(可以用 --date= 選項定制格式) %ar 作者修訂日期,按多久以前的方式顯示 %cn 提交者(committer)的名字 %ce 提交者的電子郵件地址 %cd 提交日期 %cr 提交日期,按多久以前的方式顯示 %s 提交說明 -
選項
--graph可以形象的展示分支,合并歷史$ git log --pretty --graph * commit fb40f7a259de8ec2f2edbada6f85aa855f4a6585 (HEAD -> master) | Author: shenglanya <shenglanya@corp.netease.com> | Date: Wed Mar 7 11:34:54 2018 +0800 | | add pic | * commit ec50914561593b769a98ff468de6697a6d964cbd | Author: shenglanya <shenglanya@corp.netease.com> | Date: Wed Mar 7 11:33:36 2018 +0800 | | xiugai | * commit a7372097ab8f063e17beca6fa8f82a15bb11c5e3 | Author: shenglanya <shenglanya@corp.netease.com> | Date: Wed Mar 7 11:20:05 2018 +0800 | | 提交 -
git log 的常用選項
選項 說明 -p 按補丁格式顯示每個更新之間的差異。 --stat 顯示每次更新的文件修改統(tǒng)計信息。 --shortstat 只顯示 --stat 中最后的行數(shù)修改添加移除統(tǒng)計。 --name-only 僅在提交信息后顯示已修改的文件清單。 --name-status 顯示新增、修改、刪除的文件清單。 --abbrev-commit 僅顯示 SHA-1 的前幾個字符,而非所有的 40 個字符。 --relative-date 使用較短的相對時間顯示(比如,“2 weeks ago”)。 --graph 顯示 ASCII 圖形表示的分支合并歷史。 --pretty 使用其他格式顯示歷史提交信息。可用的選項包括 oneline,short,full,fuller 和 format(后跟指定格式)。 -
限制
git log輸出的選項選項 說明 -(n) 僅顯示最近的 n 條提交 --since, --after僅顯示指定時間之后的提交。 --until, --before僅顯示指定時間之前的提交。 --author 僅顯示指定作者相關(guān)的提交。 --committer 僅顯示指定提交者相關(guān)的提交。 --grep 僅顯示含指定關(guān)鍵字的提交 -S 僅顯示添加或移除了某個關(guān)鍵字的提交
撤銷操作指令
-
重新提交:有時候我們提交完了才發(fā)現(xiàn)漏掉了幾個文件沒有添加,或者提交信息寫錯了。 此時,可以運行帶有
--amend選項的提交命令嘗試重新提交:$ git commit --amend這個命令將暫存區(qū)中的文件提交,如果自從上次提交以來還未做任何修改,則快照保持不變,你修改的只有提交信息。例如你提交后發(fā)現(xiàn)忘記了暫存某些需要的修改,可以像下面這樣操作:$ git commit -m 'initial commit' $ git add forgotten_file $ git commit --amend # 最終只會有一個提交,第二次提交將代替第一次提交的結(jié)果 取消暫存的文件:可以使用
git reset HEAD yourfile來進行取消暫存區(qū)域內(nèi)文件的暫存操作。撤銷對文件的修改:如果你不想保存對文件的修改,如何方便的將其還原成上次提交的樣子?使用
$ gitcheckout -- pic/實習(xí)學(xué)習(xí)筆記.md撤銷之前所做的修改。
Git 遠(yuǎn)程倉庫的使用
-
查看遠(yuǎn)程倉庫 : 使用
git remote命令可以列出你指定的每個遠(yuǎn)程服務(wù)器的簡寫。如果已經(jīng)克隆了自己的倉庫,那么至少能看到 origin$ cd ios-client $ git remote origin可以指定參數(shù) -v 可以查看你的讀寫權(quán)限
$ git remote -v origin https://git.ms.netease.com/netease-precious-metals-client/ios-client.git (fetch) origin https://git.ms.netease.com/netease-precious-metals-client/ios-client.git (push) -
添加遠(yuǎn)程倉庫: 運行
git remote add <shortname> <url>添加一個新的遠(yuǎn)程 Git 倉庫$ git remote origin $ git remote add test https://github.com/lanyasheng/NTAlgorithm.git $ git remote -v origin https://git.ms.netease.com/netease-precious-metals-client/ios-client.git (fetch) origin https://git.ms.netease.com/netease-precious-metals-client/ios-client.git (push) test https://github.com/lanyasheng/NTAlgorithm.git (fetch) test https://github.com/lanyasheng/NTAlgorithm.git (push)現(xiàn)在就可以使用 test 來代替整個 URL ,例如使用
git fetch test來拉取遠(yuǎn)端 Git 倉庫中有但你沒有的信息。$ git fetch test warning: no common commits remote: Counting objects: 84, done. remote: Total 84 (delta 0), reused 0 (delta 0), pack-reused 83 Unpacking objects: 100% (84/84), done. From https://github.com/lanyasheng/NTAlgorithm * [new branch] develop -> test/develop * [new branch] master -> test/master現(xiàn)在可以在本地訪問 test/master 分支了,實際上對應(yīng)遠(yuǎn)端的 master 分支。
從倉庫中抓取:
git fetch會訪問遠(yuǎn)端倉庫,從中拉取所有你沒有的信息。執(zhí)行完后,你會擁有該倉庫的所有分支引用可以用來隨時合并和查看。當(dāng)使用了git clone命令克隆一個遠(yuǎn)端倉庫時,命令會自動將其添加為遠(yuǎn)程倉庫并默認(rèn)以 “origin” 為簡寫。git fetch origin會抓取克隆(或上一次抓?。┖笮峦扑偷乃泄ぷ?。 必須注意git fetch命令會將數(shù)據(jù)拉取到你的本地倉庫 - 它并不會自動合并或修改你當(dāng)前的工作。 當(dāng)準(zhǔn)備好時你必須手動將其合并入你的工作。從倉庫上拉取:
git pull可以用來自動的抓取然后合并遠(yuǎn)程分支到當(dāng)前分支,前提是你有一個分支設(shè)置為跟蹤一個遠(yuǎn)程的分支。所以git pull == git fetch + git merge。默認(rèn)情況下,git clone會自動設(shè)置本地的 master 分支跟蹤遠(yuǎn)程倉庫的 master 分支,運行git pull通常會從最初克隆的服務(wù)器上抓取數(shù)據(jù)并自動嘗試合并到當(dāng)前所在的分支。推送到遠(yuǎn)程分支:
git push [remote-name][branch-name]指令可以將你的項目推送到服務(wù)器。例如當(dāng)你想將 master 推到 origin 時,可以使用$ git push origin master只有當(dāng)你有所克隆服務(wù)器的寫入權(quán)限,并且之前沒有人推送過時,這條命令才能生效。 當(dāng)你和其他人在同一時間克隆,他們先推送到上游然后你再推送到上游,你的推送就會毫無疑問地被拒絕。 你必須先將他們的工作拉取下來并將其合并進你的工作后才能推送-
查看遠(yuǎn)程倉庫: 如果想查看一個遠(yuǎn)程倉庫的更多信息,可以使用
$ git remote show test$ git remote show test * remote test Fetch URL: https://github.com/lanyasheng/NTAlgorithm.git Push URL: https://github.com/lanyasheng/NTAlgorithm.git HEAD branch: master Remote branches: develop tracked master tracked Local branches configured for 'git pull': develop merges with remote develop master merges with remote master Local refs configured for 'git push': develop pushes to develop (local out of date) master pushes to master (local out of date)這個命令列出了當(dāng)你在特定的分支上執(zhí)行
git push會自動地推送到哪一個遠(yuǎn)程分支。 它也同樣地列出了哪些遠(yuǎn)程分支不在你的本地,哪些遠(yuǎn)程分支已經(jīng)從服務(wù)器上移除了,還有當(dāng)你執(zhí)行git pull時哪些分支會自動合并 -
遠(yuǎn)程倉庫的移除與命名:運行
git remote rename <shortname> <url>重命名遠(yuǎn)程倉庫$ git remote rename test testNea $ git remote origin testNea -
移除遠(yuǎn)程倉庫:
$ git remote rm testNea $ git remote origin
Git 標(biāo)簽
創(chuàng)建標(biāo)簽
-
輕量標(biāo)簽 — 就像一個不會改變的分支,只是一個特定提交的引用,創(chuàng)建輕量標(biāo)簽只需要提供版本號即可。
git tag v1.4-1w$ git tag v1.4-1w $ git show commit fb40f7a259de8ec2f2edbada6f85aa855f4a6585 (HEAD -> master, tag: v1.4-1w, tag: v1.3) Author: shenglanya <shenglanya@corp.netease.com> Date: Wed Mar 7 11:34:54 2018 +0800 add pic diff --git a/pic/git存儲項目雖時間改變的快照.png b/pic/git存儲項目雖時間改變的快照.png new file mode 100644 index 0000000..1036a42 Binary files /dev/null and b/pic/git存儲項目雖時間改變的快照.png differ -
附注標(biāo)簽 — 一個存儲在 Git 數(shù)據(jù)庫中的一個完整對象,他們可以被校驗。其中包含打標(biāo)簽者的名字,電子郵件地址、日期時間,標(biāo)簽信息。并且可以使用 GNU Privacy Guard (GPG)簽名與驗證??梢允褂?code>$ git tag -a v1.3 這樣就給當(dāng)前版本打上了 v1.3 標(biāo)簽。也可以使用
$ git tag -a v1.3 -m 'my version 1.3'這樣就直接標(biāo)備注了。git show可以查看標(biāo)簽信息與對應(yīng)的提交信息$ git tag -a v1.3 $ git show commit fb40f7a259de8ec2f2edbada6f85aa855f4a6585 (HEAD -> master, tag: v1.3) Author: shenglanya <shenglanya@corp.netease.com> Date: Wed Mar 7 11:34:54 2018 +0800 add pic diff --git a/pic/git存儲項目雖時間改變的快照.png b/pic/git存儲項目雖時間改變的快照.png new file mode 100644 index 0000000..1036a42 Binary files /dev/null and b/pic/git存儲項目雖時間改變的快照.png differ
后期打標(biāo)簽
-
也可以對過去提交打標(biāo)簽。例如提交歷史如下
$ git log --pretty=oneline fb40f7a259de8ec2f2edbada6f85aa855f4a6585 (HEAD -> master, tag: v1.4-1w, tag: v1.3) add pic ec50914561593b769a98ff468de6697a6d964cbd xiugai a7372097ab8f063e17beca6fa8f82a15bb11c5e3 提交 20c944dba3f056aef30aada88d0a452e8faffcbc hehe 2713657f264a3a019580dc3a489d303fade5dc5c 第一次的修改提交可以使用
$ git tag -a v1.2 2713657表示對該校驗和的版本打上標(biāo)簽。$ git tag v1.2 v1.3 v1.4-1w $ git show v1.2 tag v1.2 Tagger: shenglanya <shenglanya@corp.netease.com> Date: Wed Mar 7 15:00:31 2018 +0800 對之前的打標(biāo)簽` commit 2713657f264a3a019580dc3a489d303fade5dc5c (tag: v1.2) Author: shenglanya <shenglanya@corp.netease.com> Date: Wed Mar 7 09:41:21 2018 +0800 第一次的修改提交 diff --git a/pic/git存儲項目雖時間改變的快照.png b/pic/git存儲項目雖時間改變的快照.png new file mode 100644 index 0000000..1036a42 Binary files /dev/null and b/pic/git存儲項目雖時間改變的快照.png differ diff --git a/pic/lifecycle.png b/pic/lifecycle.png new file mode 100644 index 0000000..922b02c Binary files /dev/null and b/pic/lifecycle.png differ diff --git a/pic/實習(xí)學(xué)習(xí)筆記.md b/pic/實習(xí)學(xué)習(xí)筆記.md new file mode 100644
Git 分支
分支簡介
簡介
Git 保存到不是文件的變化或差異,而是一系列不同時刻的文件快照。當(dāng)提交時,Git 會保存一個提交的對象。該提交對象會包含一個指向暫存內(nèi)容快照的指針,還會包含作者姓名和郵箱,提交時輸入的信息以及指向他的父對象的指針。首次提交產(chǎn)生的提交對象沒有父對象,普通提交操作產(chǎn)生的提交對象有一個父對象,而由多個分支合并產(chǎn)生的提交對象有多個父對象。
我們假設(shè)現(xiàn)在有一個工作目錄,里面包含了三個將要被暫存和提交的文件。 暫存操作會為每一個文件計算校驗和然后會把當(dāng)前版本的文件快照保存到 Git 倉庫中,最終將校驗和加入到暫存區(qū)域等待提交:
創(chuàng)建分支
- Git 創(chuàng)建新分支的本質(zhì)就是創(chuàng)建一個可以移動的新的指針。比如創(chuàng)建一個 testing 分支。
$ git branch testing這會在當(dāng)前所提交的對象上創(chuàng)建一個指針,此時如圖:

- 如何判斷 Git 當(dāng)前在哪一個分支?此時就要依靠 HEAD 指針。該指針指向當(dāng)前所在的本地分支。如圖head-to-master.png
此時 HEAD 指針指向 master 指針,也就是實際上 HEAD 指針指向的時當(dāng)前所在的本地分支。在本例中,我們?nèi)栽?master 分支上,因為 git branch 命令僅僅是創(chuàng)建了一個新分支,并沒有切換到它上面??梢允褂靡韵旅顏聿榭锤鱾€分支當(dāng)前所指的對象
$ git log --oneline --decorate
5a5f9fe (HEAD -> master) rename
fb40f7a (tag: v1.4-1w, tag: v1.3, testing) add pic
ec50914 xiugai
a737209 提交
2713657 (tag: v1.2) 第一次的修改提交
可以看到,當(dāng)前 HEAD 和 master 分支均指向 5a5f9fe 開頭的對象
分支切換
-
使用
git checkout命令可以切換分支$ git checkout testing Switched to branch 'testing' $ git log --oneline --decorate fb40f7a (HEAD -> testing, tag: v1.4-1w, tag: v1.3) add pic ec50914 xiugai a737209 提交 2713657 (tag: v1.2) 第一次的修改提交可以看到,此時 HEAD 指針指向了 testing 指針,表示當(dāng)前的本地分支切換為 testing 分支。然后在 testing 分支上進行一些操作
$ git commit -a -m 'made a change on tesing' [testing 844332b] made a change on tesing 3 files changed, 1 insertion(+) create mode 100644 pic/head-to-master.png create mode 100644 pic/test.md create mode 100644 pic/two-branches.png $ git log --oneline --decorate 844332b (HEAD -> testing) made a change on tesing fb40f7a (tag: v1.4-1w, tag: v1.3) add pic ec50914 xiugai a737209 提交 20c944d hehe 2713657 (tag: v1.2) 第一次的修改提交此時可以發(fā)現(xiàn) HEAD 指針指向 testing 指針指向了新提交的文件。[圖片上傳失敗...(image-dde0a4-1520604809580)]
此時再切換到 master 分支看一下
$ git checkout master Switched to branch 'master' $ git log --oneline --decorate 5a5f9fe (HEAD -> master) rename fb40f7a (tag: v1.4-1w, tag: v1.3) add pic ec50914 xiugai a737209 提交 2713657 (tag: v1.2) 第一次的修改提交可以發(fā)現(xiàn)此時 master 分支還指向剛剛它指向的位置,也就是[圖片上傳失敗...(image-85e5da-1520604809580)]
?
-
git checkout master一共做了兩件事:- 使 HEAD 指向 master 分支
- 將工作目錄恢復(fù)成 master 分支所指向的快照內(nèi)容,也就是忽略 testing 分支所做的修改。
若我們此時再對 master 分支上的文件上進行修改,就會產(chǎn)生分叉。因為你剛創(chuàng)建了一個新分支,并且切換過去進行了一些工作,然后后切換回了 master 分支進行了一些額外的工作。上述改動針對的是不同分支,你可以在不同分支之間來回切換并在某一時刻將他們合并。
項目分叉歷史
-
可以使用
git log命令查看分叉歷史。運行git log --oneline --decorate --graph —all,他會輸出你的提交歷史各個分支的指向以及項目的分支分叉情況。$ git log --oneline --decorate --graph --all * b551643 (HEAD -> master) made a change on master * 5a5f9fe rename | * 844332b (testing) made a change on tesing |/ * fb40f7a (tag: v1.4-1w, tag: v1.3) add pic * ec50914 xiugai * a737209 提交 * 20c944d hehe * 2713657 (tag: v1.2) 第一次的修改提交由于 Git 的分支實際上只是包含所指對象的校驗和,創(chuàng)建一個新分支僅僅相當(dāng)于往一個文件中寫入 41 個字節(jié)。
分支操作
分支的新建與合并
- 具體實例總結(jié)在此文章中 分支的新建與合并
- 需要注意的地方:
- 首先當(dāng)你想直接從當(dāng)前分支創(chuàng)建并切換到新分支時,可以使用
$ git checkout -b yourname來進行操作,這個命令等價于$ git branch yourname + $ git checkout yourname - 當(dāng)你在新分支上工作時,突然需要切換到之前開始分叉的 master 分支并且需要在 master 分支上開一個新的分支進行工作,則首先需要暫存你在 yourname 分支上還未進行暫存的修改,然后將其提交到倉庫。否則可能會跟你即將檢出的分支產(chǎn)生沖突。
- 當(dāng)你在 master 分支上開了一個新分支并且已經(jīng)解決完問題后,可以將 master 和 hotfix 進行合并,使用
$ git checkout master, $ git merge hotfix進行合并。- 快進 (Fast forward):在合并時,如果當(dāng)前的 master 分支是你要合并分支的直接上游,則 Git 會直接將 master 指針向前推進到 hotfix 上面。然后就可以將 hotfix 進行刪除。 使用
$ git branch -d hotfix - 合并提交:而如果 master 不是你要合并分支的直接上游,比如此時 master 分支已經(jīng)指向了原本 hotfix 指向的位置,則將它與 yourname 分支合并起來會比較麻煩。由于此時 master 分支已經(jīng)更新了,如果我們需要它新的內(nèi)容可以將 master 合并到 yourname 上,如果不需要可以直接等 yourname 分支任務(wù)完成后,將其合并到 master 上面。如果我們想將 yourname 合并到 master 上,首先會記錄他們兩個指針?biāo)赶虻淖詈笠粋€快照,然后記錄他們共同的祖先快照,最后將三方合并的結(jié)果做一個新的快照并且自動創(chuàng)建一個新的提交指向它。合并后可以刪除 yourname 分支。
- 快進 (Fast forward):在合并時,如果當(dāng)前的 master 分支是你要合并分支的直接上游,則 Git 會直接將 master 指針向前推進到 hotfix 上面。然后就可以將 hotfix 進行刪除。 使用
- 首先當(dāng)你想直接從當(dāng)前分支創(chuàng)建并切換到新分支時,可以使用
- 遇到?jīng)_突的分之合并:可以直接使用
git status狀態(tài)來查看具體是哪個文件產(chǎn)生了沖突,然后直接打開該文件刪除亂碼部分和不需要的部分。
分支管理(git branch 命令)
-
$ git branch命令不僅可以創(chuàng)建或刪除分支,當(dāng)不加參數(shù)時,其作用為可以查看當(dāng)前分支$ git branch * master testing其中 * 表示當(dāng)前分支
-
$ git branch -v可以查看每個分支的最后一次提交$ git branch -v * master b551643 made a change on master testing 844332b made a change on tesing -
$ git branch --merged可以查看哪些分支已經(jīng)合并到當(dāng)前分支上,同理$ git branch --no-merged$ git branch --merged * master $ git branch --no-merged testing $ git branch -d yourname可以用來刪除已經(jīng)合并的分支,如果是未合并的分支則會報錯。
分支開發(fā)工作流程
- 長期分支(最常用)
- 如只在 master 上保留穩(wěn)定的代碼,有可能僅僅是已經(jīng)發(fā)布的代碼。還有一些其他的分支如 develop 和 next 平行分支用來進行后續(xù)開發(fā),一旦在在這些分支上達到了穩(wěn)定,再將他們合并到 master 分支上。這樣在確保這些已完成的特性分支能夠通過所有的測試,并且不會引入 bug 后再將他們合并到 master 上等待下一次發(fā)布。
- 特性分支
- 特性分支被用來實現(xiàn)單一特性或相關(guān)工作,一旦工作完成它就會被刪除。這項技術(shù)可以使你快速的進行上下文切換。當(dāng)你做這么多操作時,這些分支要確保存于本地,而不會與服務(wù)器進行交互。
遠(yuǎn)程分支
- 遠(yuǎn)程引用是指對遠(yuǎn)程倉庫的引用,包括分支標(biāo)簽等。他們是你不能移動的本地引用,當(dāng)你做任何網(wǎng)絡(luò)通信操作時,他們會自動移動。遠(yuǎn)程跟蹤分支像是你上次連接到遠(yuǎn)程倉庫時,那些分支所處狀態(tài)的書簽。他們的命名格式為 (remote)/(branch) 。如果你想要看你最后一次與遠(yuǎn)程 origin 分支通信時 master 分支的狀態(tài),則可以查看 origin / master 分支。你與同事合作解決一個問題并且他們推送了一個
iss53分支,你可能有自己的本地iss53分支;但是在服務(wù)器上的分支會指向origin/iss53的提交。 - 當(dāng)與遠(yuǎn)端倉庫共同工作時,如果你不抓取fetch遠(yuǎn)端 orgin/master ,則它將會一直指向在你上次 fetch 的那個文件。此時即使你本地的 master 已經(jīng)指向很遠(yuǎn)的地方了,遠(yuǎn)端的 orgin/master 還依舊指向你上次 fetch 的那個位置。直到你下一次 fetch。
需要注意的問題
當(dāng)我們使用分支合并時,要確定是誰合并到誰:當(dāng)我們需要使用其他分支的內(nèi)容時,可以把其他分支合并到我們的分支上。但是當(dāng)我們在開發(fā)時,有時可能是從 master 或 develop 分支上拉取的工作分支,此時如果 master 或 develop 分支有更新并且我們需要用到,可以將 master 或 develop 分支拉取到我們的分支。否則,則應(yīng)該等開發(fā)完畢后,將我們的分支合并到 master 或 develop 分支上。當(dāng)開發(fā)完畢后,首先需要檢出 master 分支,然后將工作分支合并到 master 上即可。
$ git checkout master $ git merge workBranch。合并完成后,可以將工作分支刪除。$ git branch -d workBranch,需要注意的是,當(dāng)我們刪除的分支還包含未提交的內(nèi)容,分支刪除會失效。強制刪除可以使用-D當(dāng) merge 出現(xiàn)沖突時,我們可以先
$ git status來查看是哪里出現(xiàn)了問題,然后 cd 進入該文件,直接將沖突部分刪除即可解決問題。合并完成后再次執(zhí)行$ git status來查看問題是否解決。若問題解決,即可提交。當(dāng)已經(jīng)使用了
git add指令暫存的版本又經(jīng)過修改之后,需在再重新使用git add指令將最新的修改放入暫存區(qū),否則此時暫存區(qū)里只有上一次修改的內(nèi)容$ git commit指令僅僅是將暫存區(qū)內(nèi)的文件快照提交到本地倉庫中,想要推送到遠(yuǎn)程倉庫則還需要 push 操作,在 push 操作之前我們需要先$ git fetch操作將遠(yuǎn)程倉庫的需要合并的文件抓取到本地,然后進行合并,合并完成后使用$ git status指令進行查看,沒問題后再推送到遠(yuǎn)端。這里其實也可以使用$ git pull來拉取遠(yuǎn)端分支的快照,但是這容易產(chǎn)生沖突,若產(chǎn)生沖突則可以找到產(chǎn)生沖突的文件,修改沖突部分再重新提交。提交完成后若想刪掉遠(yuǎn)端工作分支,則可以使用$ git push origin --delete指令。當(dāng)我們想刪除本地暫存區(qū)中的內(nèi)容,可以使用
$ git rm --cache 文件名指令,當(dāng)我們想刪除工作區(qū)的某個文件可以使用$ git rm -f。-
當(dāng)我們想要刪除錯誤提交到本地倉庫的 commit
-
$ git reset --soft 版本庫ID僅僅撤銷已經(jīng)提交的版本庫,不會修改暫存區(qū)和工作區(qū) -
$ git reset --mixed 版本庫ID僅僅撤銷提交到版本庫和暫存區(qū)的內(nèi)容,不會修改工作區(qū)的內(nèi)容 -
$ git reset --hard 版本庫ID將工作區(qū),暫存區(qū),和版本庫記錄恢復(fù)到指定版本。
-
$ git stash branch如果使用 stash 儲藏了一些工作,然后繼續(xù)在儲藏的分支上工作,在重新應(yīng)用 stash 儲藏的文件工作時可能會有問題。 如果應(yīng)用嘗試修改剛剛儲藏的修改的文件,也就是兩次同時修改了一個文件,你會得到一個合并沖突并不得不解決它。 如果想要一個輕松的方式來再次測試儲藏的改動,可以運行git stash branch創(chuàng)建一個新分支,檢出儲藏工作時所在的提交,重新在那應(yīng)用工作,然后在應(yīng)用成功后自動扔掉儲藏。可以使用
$ git stash -all來清除工作目錄中所有冗余的未被跟蹤的文件,并且他們會被存儲在工作棧上,當(dāng)你想要恢復(fù)時也可以使用$ git stash apply恢復(fù)使用。-
當(dāng)在本地新創(chuàng)建一個分支時,需要先 push 到遠(yuǎn)端倉庫,遠(yuǎn)端倉庫才會有這個分支,否則會報錯
error: the requested upstream branch 'origin/f_tradeReverse' does not exist hint: hint: If you are planning on basing your work on an upstream hint: branch that already exists at the remote, you may need to hint: run "git fetch" to retrieve it. hint: hint: If you are planning to push out a new local branch that hint: will track its remote counterpart, you may want to use hint: "git push -u" to set the upstream config as you push. $ git fetch $ git status On branch f_tradeReverse nothing to commit, working tree clean $ git push fatal: The current branch f_tradeReverse has no upstream branch. To push the current branch and set the remote as upstream, use git push --set-upstream origin f_tradeReverse $ git push --set-upstream origin f_tradeReverse Username for 'https://git.ms.netease.com': shenglanya Password for 'https://shenglanya@git.ms.netease.com': Total 0 (delta 0), reused 0 (delta 0) remote: remote: Create merge request for f_tradeReverse: remote: https://git.ms.netease.com/preciousmetals/LDPMTrade/merge_requests/new?merge_request%5Bsource_branch%5D=f_tradeReverse remote: To https://git.ms.netease.com/preciousmetals/LDPMTrade.git * [new branch] f_tradeReverse -> f_tradeReverse Branch 'f_tradeReverse' set up to track remote branch 'f_tradeReverse' from 'origin'. git 拉取遠(yuǎn)程分支并且創(chuàng)建本地分支
$ git checkout -b 本地分支名x origin/遠(yuǎn)程分支名x-
如果寫錯名字,重命名遠(yuǎn)程為dev1。思路:刪除遠(yuǎn)程分支、重命名本地分支、重新提交一個遠(yuǎn)程分支
1、git push --delete origin dev——刪除遠(yuǎn)程分支
2、git branch -m dev dev1——重命名本地分支為dev1
3、git push origin dev1——重新推送遠(yuǎn)端倉庫分支名稱為dev1
-
如何刪除本地的文件的修改?
- 如果是刪除已經(jīng)暫存的文件,則直接使用
$ git reset HEAD 文件名 - 如果是要刪除未暫存的文件,使用
$ git checkout --文件名這樣會使得這個文件去掉所有還未暫存的修改 - 如果刪除未跟蹤的文件,使用
$ git clean -df - 刪除不想要的修改
$ git stash && $ git stash clear - 刪除本地分支
$ git branch -D BranchName
- 如果是刪除已經(jīng)暫存的文件,則直接使用
-
刪除遠(yuǎn)端分支
- 刪除本地的遠(yuǎn)端分支
$ git branch -r -D origin/BranchName - 刪除遠(yuǎn)端服務(wù)器的分支
$ git push origin -d BranchName
- 刪除本地的遠(yuǎn)端分支
-
打 tag
- 在本地打 tag :
$ git tag 4.20.1 - 將 tag 推送到遠(yuǎn)端 :
$ git push origin :4.20.1
- 在本地打 tag :
查看遠(yuǎn)端分支
$ git branch -r從遠(yuǎn)端拉取分支
$ git checkout -b x origin/x
總結(jié)
- 本次 Git 基礎(chǔ)學(xué)習(xí)總結(jié)到現(xiàn)在就告一段落,文章由于時間,精力和自己本身能力原因并未能夠完整的寫完,留到日后的學(xué)習(xí)工作中當(dāng)有時間和精力,以及對 Git 的使用更加了解后,將繼續(xù)完善。
