Git簡(jiǎn)單介紹
Git
是一個(gè)分布式版本控制軟件,最初由Linus Torvalds
創(chuàng)作,于2005年以GPL
發(fā)布。最初目的是為更好地管理Linux
內(nèi)核開(kāi)發(fā)而設(shè)計(jì)。
Git工作流程以及各個(gè)區(qū)域
- Workspace:工作區(qū)
- Staging/Index:暫存區(qū)
- Local Repository:本地倉(cāng)庫(kù)(可修改)
- /refs/remotes:遠(yuǎn)程倉(cāng)庫(kù)的引用(不可修改)
- Remote:遠(yuǎn)程倉(cāng)庫(kù)
Git文件狀態(tài)變化
Git各種命令
Git簡(jiǎn)單命令
# 在當(dāng)前目錄新建一個(gè)git倉(cāng)庫(kù)
git init
# 打開(kāi)git倉(cāng)庫(kù)圖形界面
gitk
# 顯示所有變更信息
git status
# 刪除所有Untracked files
git clean -fd
# 下載遠(yuǎn)程倉(cāng)庫(kù)的所有更新
git fetch remote
# 下載遠(yuǎn)程倉(cāng)庫(kù)的所有更新,并且Merge
git pull romote branch-name
# 查看上次commit id
git rev-parse HEAD
# 將指定分支合并到當(dāng)前分支
git merge branch-name
# 將最近的一次commit打包到patch文件中
git format-patch HEAD^
# 將patch文件 添加到本地倉(cāng)庫(kù)
git am patch-file
# 查看指定文件修改歷史
git blame file-name
Git常用命令
git clone
# 將遠(yuǎn)程git倉(cāng)庫(kù)克隆到本地
git clone url
# 將遠(yuǎn)程git倉(cāng)庫(kù)克隆到本地
git clone -b branch url
git stash
# 將修改過(guò),未add到Staging區(qū)的文件,暫時(shí)存儲(chǔ)起來(lái)
git stash
# 恢復(fù)之前stash存儲(chǔ)的內(nèi)容
git stash apply
# 保存stash 并寫message
git stash save "stash test"
# 查看stash了哪些存儲(chǔ)
git stash list
# 將stash@{1}存儲(chǔ)的內(nèi)容還原到工作區(qū)
git stash apply stash@{1}
# 刪除stash@{1}存儲(chǔ)的內(nèi)容
git stash drop stash@{1}
# 刪除所有緩存的stash
git stash clear
git config
# 配置git圖形界面編碼為utf-8
git config --global gui.encoding=utf-8
# 設(shè)置全局提交代碼的用戶名
git config --global user.name name
# 設(shè)置全局提交代碼時(shí)的郵箱
git config --global user.email email
# 設(shè)置當(dāng)前項(xiàng)目提交代碼的用戶名
git config user.name name
git remote
# 顯示所有遠(yuǎn)程倉(cāng)庫(kù)
git remote -v
# 增加一個(gè)新的遠(yuǎn)程倉(cāng)庫(kù)
git remote add name url
# 刪除指定遠(yuǎn)程倉(cāng)庫(kù)
git remote remove name
# 獲取指定遠(yuǎn)程倉(cāng)庫(kù)的詳細(xì)信息
git remote show origin
git add
# 添加所有的修改到Staging區(qū)
git add .
git add --all
# 添加指定文件到Staging區(qū)
git add file
# 添加多個(gè)修改的文件到Staging區(qū)
git add file1 file2
# 添加修改的目錄到Staging區(qū)
git add dir
# 添加所有src目錄下main開(kāi)頭的所有文件到Staging區(qū)
git add src/main*
git commit
# 提交Staging區(qū)的代碼到本地倉(cāng)庫(kù)區(qū)
git commit -m "message"
# 提交Staging中在指定文件到本地倉(cāng)庫(kù)區(qū)
git commit file1 file2 -m "message"
# 使用新的一次commit,來(lái)覆蓋上一次commit
git commit --amend -m "message"
# 修改上次提交的用戶名和郵箱
git commit --amend --author="name email>" --no-edit
git branch
# 列出本地所有分支
git branch
# 列出本地所有分支 并顯示最后一次提交的哈希值
git branch -v
# 在-v 的基礎(chǔ)上 并且顯示上游分支的名字
git branch -vv
# 列出上游所有分支
git branch -r
# 新建一個(gè)分支,但依然停留在當(dāng)前分支
git branch branch-name
# 刪除分支
git branch -d branch-name
# 設(shè)置分支上游
git branch --set-upstream-to origin/master
# 本地分支重命名
git branch -m old-branch new-branch
git checkout
# 創(chuàng)建本地分支并關(guān)聯(lián)遠(yuǎn)程分支
git checkout -b local-branch origin/remote-branch
# 新建一個(gè)分支,且切換到新分支
git checkout -b branch-name
# 切換到另一個(gè)分支
git checkout branch-name
# 撤銷工作區(qū)文件的修改,跟上次Commit一樣
git checkout commit-file
git tag
# 創(chuàng)建帶有說(shuō)明的標(biāo)簽
git tag -a v1.4 -m 'my version 1.4'
# 打標(biāo)簽
git tag tag-name
# 查看所有標(biāo)簽
git tag
# 給指定commit打標(biāo)簽
git tag tag-name commit-id
# 刪除標(biāo)簽
git tag -d tag-name
git push
# 刪除遠(yuǎn)程分支
git push origin :master
# 刪除遠(yuǎn)程標(biāo)簽
git push origin --delete tag tag-name
# 上傳本地倉(cāng)庫(kù)到遠(yuǎn)程分支
git push remote branch-name
# 強(qiáng)行推送當(dāng)前分支到遠(yuǎn)程分支
git push remote branch-name --force
# 推送所有分支到遠(yuǎn)程倉(cāng)庫(kù)
git push remote --all
# 推送所有標(biāo)簽
git push --tags
# 推送指定標(biāo)簽
git push origin tag-name
# 刪除遠(yuǎn)程標(biāo)簽(需要先刪除本地標(biāo)簽)
git push origin :refs/tags/tag-name
# 將本地dev分支push到遠(yuǎn)程master分支
git push origin dev:master
git reset
# 將未commit的文件移出Staging區(qū)
git reset HEAD
# 重置Staging區(qū)與上次commit的一樣
git reset --hard
# 重置Commit代碼和遠(yuǎn)程分支代碼一樣
git reset --hard origin/master
# 回退到上個(gè)commit
git reset --hard HEAD^
# 回退到前3次提交之前,以此類推,回退到n次提交之前
git reset --hard HEAD~3
回退到指定commit
git reset --hard commit-id
git diff
# 查看文件在工作區(qū)和暫存區(qū)區(qū)別
git diff file-name
# 查看暫存區(qū)和本地倉(cāng)庫(kù)區(qū)別
git diff --cached file-name
# 查看文件和另一個(gè)分支的區(qū)別
git diff branch-name file-name
# 查看兩次提交的區(qū)別
git diff commit-id commit-id
git show
# 查看指定標(biāo)簽的提交信息
git show tag-name
# 查看具體的某次改動(dòng)
git show commit-id
git log
# 指定文件夾 log
git log --pretty=format:"%h %cn %s %cd" --author="iisheng\|勝哥" --date=short src
# 查看指定用戶指定format 提交
git log --pretty=format:"%h %cn %s %cd" --author=iisheng --date=short
# 查看該文件的改動(dòng)歷史
git log --pretty=oneline file
# 圖形化查看歷史提交
git log --graph --pretty=oneline --abbrev-commit
# 統(tǒng)計(jì)倉(cāng)庫(kù)提交排名前5
git log --pretty='%aN' | sort | uniq -c | sort -k1 -n -r | head -n 5
# 查看指定用戶添加代碼行數(shù),和刪除代碼行數(shù)
git log --author="iisheng" --pretty=tformat: --numstat | awk '{ add += $1 ; subs += $2 } END { printf "added lines: %s removed lines : %s \n",add,subs }'
git rebase
# 將指定分支合并到當(dāng)前分支
git rebase branch-name
# 執(zhí)行commit id 將rebase 停留在指定commit 處
git rebase -i commit-id
# 執(zhí)行commit id 將rebase 停留在 項(xiàng)目首次commit處
git rebase -i --root
git restore
# 恢復(fù)第一次add 的文件,同 git rm --cached
git restore --staged file
# 移除staging區(qū)的文件,同 git checkout
git restore file
git revert
# 撤銷前一次commit
git revert HEAD
# 撤銷前前一次commit
git revert HEAD^
# 撤銷指定某次commit
git revert commit-id
Git騷操作
Git命令不能自動(dòng)補(bǔ)全?(Mac版)
我見(jiàn)過(guò)有的人使用Git
別名,反正因?yàn)橛凶詣?dòng)補(bǔ)全的存在,我從來(lái)沒(méi)用過(guò)Git
別名。不過(guò)我的確將我的rm -rf
命令替換成了別的腳本了...
安裝bash-completion
brew install bash-completion
添加 bash-completion 到 ~/.bash_profile
:
if [ -f $(brew --prefix)/etc/bash_completion ]; then
. $(brew --prefix)/etc/bash_completion
fi
shell
有不同種類,我這里使用的是bash
。
代碼沒(méi)寫完,突然要切換到別的分支怎么辦?
暫存未提交的代碼
還原暫存的代碼
怎么合并其他分支的指定Commit?
使用cherry-pick
命令
git cherry-pick 指定commit-id
本地臨時(shí)代碼不想提交,怎么一次性清空?
還原未commit
的本地更改的代碼
還原包含commit
的代碼,到跟遠(yuǎn)程分支相同
git reset --hard origin/master
已經(jīng)提交的代碼,不需要了,怎么當(dāng)做沒(méi)提交過(guò)?
還原到上次commit
還原到當(dāng)前之前的幾次commit
強(qiáng)制推送到遠(yuǎn)程分支,確保沒(méi)有其他人在push
,不然可能會(huì)丟失代碼
git push origin develop --force
歷史commit作者郵箱寫錯(cuò)了,怎么一次性改過(guò)來(lái)?
使用git filter-branch
命令。
復(fù)制下面的腳本,替換相關(guān)變量
OLD_EMAIL
CORRECT_NAME
CORRECT_EMAIL
腳本如下:
#!/bin/sh
git filter-branch --env-filter '
OLD_EMAIL="your-old-email@example.com"
CORRECT_NAME="Your Correct Name"
CORRECT_EMAIL="your-correct-email@example.com"
if [ "$GIT_COMMITTER_EMAIL" = "$OLD_EMAIL" ]
then
export GIT_COMMITTER_NAME="$CORRECT_NAME"
export GIT_COMMITTER_EMAIL="$CORRECT_EMAIL"
fi
if [ "$GIT_AUTHOR_EMAIL" = "$OLD_EMAIL" ]
then
export GIT_AUTHOR_NAME="$CORRECT_NAME"
export GIT_AUTHOR_EMAIL="$CORRECT_EMAIL"
fi
' --tag-name-filter cat -- --branches --tags
強(qiáng)制推送替換
git push --force --tags origin 'refs/heads/*'
不小心把不該提交的文件commit了,怎么永久刪除?
也是使用git filter-branch
命令。
git filter-branch --force --index-filter \
"git rm --cached --ignore-unmatch FILE-PATH-AND-NAME" \
--prune-empty --tag-name-filter cat -- --all
強(qiáng)制推送覆蓋遠(yuǎn)程分支。
git push origin --force --all
強(qiáng)制推送覆蓋遠(yuǎn)程tag
。
git push origin --force --tags
怎么保證團(tuán)隊(duì)成員提交的代碼都是可運(yùn)行的?
這里想說(shuō)的是使用git hooks
,一般在項(xiàng)目目錄.git/hooks
,客戶端可以使用hooks
,控制團(tuán)隊(duì)commit
提交規(guī)范,或者push
之前,自動(dòng)編譯項(xiàng)目校驗(yàn)項(xiàng)目可運(yùn)行。服務(wù)端可以使用hooks
,控制push之后自動(dòng)構(gòu)建項(xiàng)目,merge
等自動(dòng)觸發(fā)單元測(cè)試等。
git reset --hard
命令,執(zhí)行錯(cuò)了,能恢復(fù)嗎?
查看當(dāng)前commit log
誤操作git reset --hard 8529cb7
執(zhí)行git reflog
還原到之前的樣子
公司使用GitLab,平時(shí)還用GitHub,多賬號(hào)SSH,如何配置?
編輯 ~/.ssh/config
文件 沒(méi)有就創(chuàng)建
# github
Host github.com
Port 22
HostName github.com
PreferredAuthentications publickey
AddKeysToAgent yes
IdentityFile ~/.ssh/github_id_rsa
UseKeychain yes
User iisheng
# gitlab
Host gitlab.iisheng.cn
Port 22
HostName gitlab.iisheng.cn
PreferredAuthentications publickey
AddKeysToAgent yes
IdentityFile ~/.ssh/gitlab_id_rsa
UseKeychain yes
User iisheng
Git commits歷史如何變得清爽起來(lái)?
多用git rebase
。
比如,開(kāi)發(fā)分支是feature
,主干分支是master
。我們?cè)谶M(jìn)行代碼合并的時(shí)候,可以執(zhí)行下面的命令。
# 切換當(dāng)前分支到feature
git checkout feature
# 將當(dāng)前分支代碼變基為基于master
git rebase master
然后我們?cè)偾袚Q到master
分支,執(zhí)行git merge feature
,就可以進(jìn)行快進(jìn)式合并了,commmits
歷史就不會(huì)有交叉了。后文我們會(huì)詳細(xì)講解。
git rebase
會(huì)更改commit歷史,請(qǐng)謹(jǐn)慎使用。
下面的圖是Guava
項(xiàng)目的commit
記錄。
如何修改已經(jīng)提交的commit信息?
原始Git
提交記錄是這樣的
執(zhí)行git rebase -i 070943d
,對(duì)指定commitId之前的提交,進(jìn)行修改
修改后Git
提交記錄變成了這樣
git rebase -i
非常實(shí)用,還可以將多個(gè)commit合并成一個(gè)等很多事情,務(wù)必要記下。
不小心執(zhí)行了git stash clear
怎么辦?
執(zhí)行之后,可以找到相關(guān)丟失的commit-id
,然后merge
一下即可。
該命令上可以找回git add
之后被弄丟的文件。
啥?你沒(méi)執(zhí)行過(guò)git add
代碼就丟了?別怕,一般編譯器有Local History
趕緊去試試吧。
詳解git merge
我們執(zhí)行git merge
命令的時(shí)候,經(jīng)常會(huì)看到Fast-forward
字樣,Fast-forward
到底是個(gè)什么東西?
其實(shí),git merge
一般有三種場(chǎng)景。
快進(jìn)式合并
舉個(gè)栗子,假如初始存在master
和hotfix
分支是這樣的。
然后我們?cè)?code>hotfix分支加了些代碼,分支變成這樣了。
這個(gè)時(shí)候,我們將hotfix
分支,merge
到master
,即執(zhí)行git merge hotfix
。
由于的分支hotfix
所指向的提交C3
是C2
的直接后繼, 因此Git
會(huì)直接將指針向前移動(dòng)。換句話說(shuō),如果順著一個(gè)分支走下去能夠到達(dá)另一個(gè)分支,那么Git
在合并兩者的時(shí)候, 只會(huì)簡(jiǎn)單的將指針向前推進(jìn)(指針右移),因?yàn)檫@種情況下的合并操作沒(méi)有需要解決的分歧——這就叫做 快進(jìn)(fast-forward)。
三方合并
再舉個(gè)栗子,假如初始存在feature
和master
分支情況是這樣的。
然后我們?cè)?code>feature分支加了些代碼,而master
分支也有人加了代碼,現(xiàn)在分支變成這樣了。
這個(gè)時(shí)候,我們將feature
分支,merge
到master
,即執(zhí)行git merge feature
。
和之前將分支指針向前推進(jìn)所不同的是,Git
將此次三方合并的結(jié)果做了一個(gè)新的快照并且自動(dòng)創(chuàng)建一個(gè)新的提交指向它。這個(gè)被稱作一次合并提交,它的特別之處在于他有不止一個(gè)父提交。
所以我們也知道了,為什么有的時(shí)候merge之后會(huì)產(chǎn)生新的commit,而有的時(shí)候沒(méi)有。
遇到?jīng)_突時(shí)的合并
如果在兩個(gè)分支分別對(duì)同一個(gè)文件做了改動(dòng),Git
就沒(méi)法直接合并他們。當(dāng)遇到?jīng)_突的時(shí)候,Git
會(huì)自動(dòng)停下來(lái),等待我們解決沖突。就像這樣
$ git merge dev
Auto-merging 111.txt
CONFLICT (content): Merge conflict in 111.txt
Automatic merge failed; fix conflicts and then commit the result.
我們可以在合并沖突后的任意時(shí)刻使用git status
命令來(lái)查看那些因包含合并沖突而處于未合并unmerged
狀態(tài)的文件。
$ git status
On branch master
You have unmerged paths.
(fix conflicts and run "git commit")
(use "git merge --abort" to abort the merge)
Unmerged paths:
(use "git add file>..." to mark resolution)
both modified: 111.txt
no changes added to commit (use "git add" and/or "git commit -a")
待解決沖突的文件Git
會(huì)以未合并的狀態(tài)標(biāo)識(shí)出來(lái),出現(xiàn)沖突的文件會(huì)出現(xiàn)一些特殊的區(qū)段,看起來(lái)像下面的樣子。
HEAD
111aaa
=======
111b
>>>>>>> dev
后面的是當(dāng)前分支的引用,我們的例子中,就代表master
分支。>>>>>>>
后面表示的是要合并到當(dāng)前分支的分支,即dev
分支。=======
的上半部分,表示當(dāng)前分支的代碼。下半部分表示dev
分支的代碼。
我們可以把上面的測(cè)試內(nèi)容改成下面的樣子來(lái)解決沖突
在解決了所有文件里的沖突之后,對(duì)每個(gè)文件使用git add
命令來(lái)將其標(biāo)記為沖突已解決。
解決沖突的過(guò)程中,每一步都可以執(zhí)行git status
查看當(dāng)前狀態(tài),Git
也會(huì)給出相應(yīng)提示,進(jìn)行下一步操作。當(dāng)我們所有的文件都暫存之后時(shí),執(zhí)行git status
時(shí),Git
會(huì)給我們看起來(lái)像下面的這種提示
$ git status
On branch master
All conflicts fixed but you are still merging.
(use "git commit" to conclude merge)
然后,我們根據(jù)提示執(zhí)行git commit
。
Merge branch 'dev'
# Conflicts:
# 111.txt
#
# It looks like you may be committing a merge.
# If this is not correct, please remove the file
# .git/MERGE_HEAD
# and try again.
# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
#
# On branch master
# All conflicts fixed but you are still merging.
#
然后,我們保存這次提交就完成了這次沖突合并。
詳解git rebase
rebase做了什么
舉個(gè)栗子。我們同樣用剛才merge
的場(chǎng)景。
如果不用rebase
,使用merge
是下面這樣的,合并分支的時(shí)候會(huì)產(chǎn)生一個(gè)合并提交,而且會(huì)有分支交叉的情況。
使用rebase
是下面這樣的。
然后,切換到master
分支,進(jìn)行一次快進(jìn)式合并。
變基實(shí)際上就是基于其他分支重塑當(dāng)前分支。變基之后,當(dāng)前分支就相當(dāng)于是基于最新的其他分支新加了一些commit,這樣的話就可以進(jìn)行快進(jìn)式合并了。
rebase原理
它的原理是首先找到這兩個(gè)分支(即當(dāng)前分支 dev
、變基操作的目標(biāo)基底分支master
)的最近共同祖先 C2
,然后對(duì)比當(dāng)前分支相對(duì)于該祖先的歷次提交,提取相應(yīng)的修改并存為臨時(shí)文件, 然后將當(dāng)前分支指向目標(biāo)基底C3
, 最后以此將之前另存為臨時(shí)文件的修改依序應(yīng)用,也就是在C3
后面添加C4'
、C5'
。
Git對(duì)象與快照
提到Git
,總有人會(huì)說(shuō)快照,快照是個(gè)什么鬼?
實(shí)際上,Git
是一個(gè)內(nèi)容尋址文件系統(tǒng),其核心部分是一個(gè)簡(jiǎn)單的鍵值對(duì)數(shù)據(jù)庫(kù)。將Git
中的對(duì)象,存儲(chǔ)在.git/objects
目錄下。
Git
對(duì)象主要分為,數(shù)據(jù)對(duì)象(blob object)、樹(shù)對(duì)象(tree object)、提交對(duì)象(commit object)、標(biāo)簽對(duì)象(tag object)。
數(shù)據(jù)對(duì)象
我們新建一個(gè)目錄,然后在該目錄下執(zhí)行git init
初始化一個(gè)Git
項(xiàng)目。
然后,查看.git/objects
目錄下都有什么。
$ find .git/objects
.git/objects
.git/objects/pack
.git/objects/info
接著,我們寫一個(gè)文件echo '1111' > 111.txt
,并執(zhí)行git add
之后,再查看。
$ find .git/objects
.git/objects
.git/objects/5f
.git/objects/5f/2f16bfff90e6620509c0cf442e7a3586dad8fb
.git/objects/pack
.git/objects/info
我們發(fā)現(xiàn).git/objects
目錄下,多了個(gè)文件和目錄。實(shí)際上,Git
會(huì)將我們的文件數(shù)據(jù)外加一個(gè)頭部信息header
一起做SHA-1
校驗(yàn)運(yùn)算而得到校驗(yàn)和。然后,校驗(yàn)和的前2個(gè)字符用于命名子目錄,余下的38個(gè)字符則用作文件名。
我們可以使用下面的命令,顯示在Git
對(duì)象中存儲(chǔ)的內(nèi)容。
$ git cat-file -p 5f2f16bfff90e6620509c0cf442e7a3586dad8fb
1111
這就是我們?cè)谏衔膶懭氲奈募?nèi)容。
上述類型的對(duì)象稱之為數(shù)據(jù)對(duì)象(blob object)。數(shù)據(jù)對(duì)象,僅保存了文件內(nèi)容,而文件名字沒(méi)有被保存。
樹(shù)對(duì)象
數(shù)據(jù)對(duì)象大致對(duì)應(yīng)UNIX
中的inodes
或文件內(nèi)容,樹(shù)對(duì)象則對(duì)應(yīng)了UNIX
中的目錄項(xiàng)。一個(gè)樹(shù)對(duì)象包含了一條或多條樹(shù)對(duì)象記錄(tree entry),每條記錄含有一個(gè)指向數(shù)據(jù)對(duì)象或者子樹(shù)對(duì)象的SHA-1
指針,以及相應(yīng)的模式、類型、文件名信息。
通常,Git
根據(jù)某一時(shí)刻暫存區(qū)(即index
區(qū)域)所表示的狀態(tài)創(chuàng)建并記錄一個(gè)對(duì)應(yīng)的樹(shù)對(duì)象。
當(dāng)我們執(zhí)行過(guò)git add
之后,暫存區(qū)就有內(nèi)容了,我們可以通過(guò)Git
底層命令,生成樹(shù)對(duì)象。
$ git write-tree
b716c7b049ccd9048b0566a57cfd516c17c1e39f
查看該樹(shù)對(duì)象的內(nèi)容。
$ git cat-file -p b716c7b049ccd9048b0566a57cfd516c17c1e39f
100644 blob 5f2f16bfff90e6620509c0cf442e7a3586dad8fb 111.txt
提交對(duì)象
數(shù)據(jù)對(duì)象保存了數(shù)據(jù)的內(nèi)容,樹(shù)對(duì)象可以表示當(dāng)前目錄的快照。但是,若想重用這些快照,必須記住樹(shù)對(duì)象的SHA-1
哈希值。而且,我們也不知道是誰(shuí)保存了這些快照,在什么時(shí)刻保存的,以及為什么保存這些快照。而以上這些,正是
提交對(duì)象(commit object)
能保存的基本信息。
我們對(duì)當(dāng)前暫存區(qū)進(jìn)行一次提交,git commit -m "first commit"
。
然后查看一下log
找到該次提交的commit
哈希值。
$ git log --oneline
5281f7e (HEAD -> master) first commit
接著,我們查看一下該提交對(duì)象的內(nèi)容。
$ git cat-file -p 5281f7e
tree b716c7b049ccd9048b0566a57cfd516c17c1e39f
author iisheng ***@gmail.com> 1596073568 +0800
committer iisheng ***@gmail.com> 1596073568 +0800
first commit
提交對(duì)象的格式很簡(jiǎn)單:它先指定一個(gè)頂層樹(shù)對(duì)象,代表當(dāng)前項(xiàng)目快照;然后是可能存在的父提交(前面描述的提交對(duì)象并不存在任何父提交);之后是作者/提交者信息(依據(jù)你的user.name
和user.email
配置來(lái)設(shè)定,外加一個(gè)時(shí)間戳);留空一行,最后是提交注釋。
標(biāo)簽對(duì)象
標(biāo)簽對(duì)象(tag object) 非常類似于一個(gè)提交對(duì)象——它包含一個(gè)標(biāo)簽創(chuàng)建者信息、一個(gè)日期、一段注釋信息,以及一個(gè)指針。主要的區(qū)別在于,標(biāo)簽對(duì)象通常指向一個(gè)提交對(duì)象,而不是一個(gè)樹(shù)對(duì)象。它像是一個(gè)永不移動(dòng)的分支引用——永遠(yuǎn)指向同一個(gè)提交對(duì)象,只不過(guò)給這個(gè)提交對(duì)象加上一個(gè)更友好的名字罷了。
實(shí)際上Git
中的各種對(duì)象都是類似的,只不過(guò)因?yàn)楦鞣N對(duì)象自身功能不同,存儲(chǔ)結(jié)構(gòu)不同而已。
Git引用-我從遠(yuǎn)程拉的代碼不是最新的?
Git
引用相當(dāng)于是Git
中特定哈希值的別名。一長(zhǎng)串的哈希值不是很友好,但是起個(gè)別名,我們就可以像這樣git show master
、git log master
的去使用他們。
Git
中的引用存儲(chǔ)在.git/refs
目錄下。我們可以執(zhí)行find .git/refs/
查看當(dāng)前Git
項(xiàng)目中都存在哪些引用。
HEAD引用
在.git
目錄下有一個(gè)名字叫做HEAD
的文件,HEAD
文件通常是一個(gè)符號(hào)引用(symbolic reference)指向目前所在的分支。所謂符號(hào)引用,表示它是一個(gè)指向其他引用的指針。
如果我們?cè)诠ぷ鲄^(qū)checkout
一個(gè)SHA-1
值,HEAD
引用也會(huì)指向這個(gè)包含Git
對(duì)象的SHA-1
值。
標(biāo)簽引用
Git
標(biāo)簽分為,附注標(biāo)簽和輕量標(biāo)簽。輕量標(biāo)簽,使用 git tag v1.0
即可創(chuàng)建。附注標(biāo)簽需要使用-a
選項(xiàng),即git tag -a v1.0 -m "my version 1.0"
這種。
輕量標(biāo)簽就是一個(gè)固定的引用。附注標(biāo)簽需要?jiǎng)?chuàng)建標(biāo)簽對(duì)象,并記錄一個(gè)引用來(lái)指向該標(biāo)簽對(duì)象。
遠(yuǎn)程引用
不熟悉Git
的同學(xué),可能會(huì)犯這樣一個(gè)錯(cuò)誤。其他同學(xué)讓他拉取一下遠(yuǎn)程最新的master
分支代碼,他可能直接用IDE
找到本地的遠(yuǎn)程分支的引用,也就是origin/master
,直接checkout
一個(gè)本地分支。
其實(shí),origin/master
只是遠(yuǎn)程分支的一個(gè)引用,不一定跟遠(yuǎn)程分支代碼同步,我們可以用git fetch
或者git pull
來(lái)讓origin/master
和遠(yuǎn)程分支同步。
參考文獻(xiàn):
[1]: https://git-scm.com/
到此這篇關(guān)于Git科普文,Git基本原理及各種騷操作(推薦)的文章就介紹到這了,更多相關(guān)Git基本原理內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
您可能感興趣的文章:- vue-cli創(chuàng)建的項(xiàng)目中的gitHooks原理解析
- Git原理和常用操作
- Git使用基礎(chǔ)篇(一些常用命令和原理)
- C#/.NET使用git命令行來(lái)操作git倉(cāng)庫(kù)的方法示例
- Git代碼提交流程及git命令匯總(基礎(chǔ)篇)
- Linux中Git集中操作命令匯總