- 概述
本章節摘自菜鳥教程
原文鏈接:https://www.runoob.com/git/git-tutorial.html
-
- 簡介
Git 是一個開源的分佈式版本控制系統,用於敏捷高效地處理任何或小或大的項目。
Git 是 Linus Torvalds 爲了幫助管理 Linux 內核開發而開發的一個開放源碼的版本控制軟件。
Git 與常用的版本控制工具 CVS, Subversion 等不同,它採用了分佈式版本庫的方式,不必服務器端軟件支持。
-
- Git與SVN區別
Git 不僅僅是個版本控制系統,它也是個內容管理系統(CMS),工作管理系統等。
如果你是一個具有使用 SVN 背景的人,你需要做一定的思想轉換,來適應 Git 提供的一些概念和特徵。
Git 與 SVN 區別點:
1、Git 是分佈式的,SVN 不是:這是 Git 和其它非分佈式的版本控制系統,例如 SVN,CVS 等,最核心的區別。
2、Git 把內容按元數據方式存儲,而 SVN 是按文件:所有的資源控制系統都是把文件的元信息隱藏在一個類似 .svn、.cvs 等的文件夾裏。
3、Git 分支和 SVN 的分支不同:分支在 SVN 中一點都不特別,其實它就是版本庫中的另外一個目錄。
4、Git 沒有一個全局的版本號,而 SVN 有:目前爲止這是跟 SVN 相比 Git 缺少的最大的一個特徵。
- Git 的內容完整性要優於 SVN:Git 的內容存儲使用的是 SHA-1 哈希算法。這能確保代碼內容的完整性,確保在遇到磁盤故障和網絡問題時降低對版本庫的破壞。
- 基礎概念
- 工作流程
注:此節爲搬運菜鳥教程中的文章,搬運鏈接https://www.runoob.com/git/git-workflow.html
Git的一般工作流程如下:
1、克隆 Git 資源作爲工作目錄。
2、在克隆的資源上添加或修改文件。
3、如果其他人修改了,你可以更新資源。
4、在提交前查看修改。
5、提交修改。
6、在修改完成後,如果發現錯誤,可以撤回提交併再次修改並提交。
下圖展示了 Git 的工作流程:
-
- 工作區、暫存區與版本庫
注:此節爲搬運菜鳥教程中的文章,搬運鏈接https://www.runoob.com/git/git-workspace-index-repo.html
工作區:就是你在電腦裏能看到的目錄。
暫存區:英文叫stage, 或index。一般存放在 ".git目錄下" 下的index文件(.git/index)中,所以我們把暫存區有時也叫作索引(index)。
版本庫:工作區有一個隱藏目錄.git,這個不算工作區,而是Git的版本庫。
下面這個圖展示了工作區、版本庫中的暫存區和版本庫之間的關係:
圖中左側爲工作區,右側爲版本庫。在版本庫中標記爲 "index" 的區域是暫存區(stage, index),標記爲 "master" 的是 master 分支所代表的目錄樹。
圖中我們可以看出此時 "HEAD" 實際是指向 master 分支的一個"遊標"。所以圖示的命令中出現 HEAD 的地方可以用 master 來替換。
圖中的 objects 標識的區域爲 Git 的對象庫,實際位於 ".git/objects" 目錄下,裏面包含了創建的各種對象及內容。
當對工作區修改(或新增)的文件執行 "git add" 命令時,暫存區的目錄樹被更新,同時工作區修改(或新增)的文件內容被寫入到對象庫中的一個新的對象中,而該對象的ID被記錄在暫存區的文件索引中。
當執行提交操作(git commit)時,暫存區的目錄樹寫到版本庫(對象庫)中,master 分支會做相應的更新。即 master 指向的目錄樹就是提交時暫存區的目錄樹。
當執行 "git reset HEAD" 命令時,暫存區的目錄樹會被重寫,被 master 分支指向的目錄樹所替換,但是工作區不受影響。
當執行 "git rm --cached <file>" 命令時,會直接從暫存區刪除文件,工作區則不做出改變。
當執行 "git checkout ." 或者 "git checkout -- <file>" 命令時,會用暫存區全部或指定的文件替換工作區的文件。這個操作很危險,會清除工作區中未添加到暫存區的改動。
當執行 "git checkout HEAD ." 或者 "git checkout HEAD <file>" 命令時,會用 HEAD 指向的 master 分支中的全部或者部分文件替換暫存區和以及工作區中的文件。這個命令也是極具危險性的,因爲不但會清除工作區中未提交的改動,也會清除暫存區中未提交的改動。
- 常用命令
- git init
命令 |
解析 |
git init |
在本地將一個目錄初始化爲一個倉庫 |
-
- git config
命令 |
解析 |
git config --list |
展示當前所有配置 |
git config --global user.name “<username>” |
配置全局username |
git config --global user.email “<email>” |
配置全局email |
-
- 生成ssh key
命令 |
解析 |
ssh-keygen -t rsa -C “<email>” |
1. 將生成的公鑰添加進remote中,即可對該倉庫該remote進行操作; 2. 可以使用cd ~/.ssh命令查看是否已經生成了ssh key; 3. windows系統中通常生成的ssh key文件位於C/用戶/Administrator/.ssh路徑下; |
-
- git clone
命令 |
解析 |
git clone <url> |
克隆獲取遠端倉庫 |
git clone <url> -b <branch> |
克隆獲取遠端倉庫的branch分支 |
-
- git remote
命令 |
解析 |
git remote add <name> <url> |
添加遠端倉庫,命名別名爲<name> |
git remote -v |
查看添加的遠端倉庫詳情列表 |
git remote remove <name> |
移除名爲<name>的遠端 |
git remote rename <old> <new> |
重命名 |
-
- git status
命令 |
解析 |
git status |
查看我們當前分支狀態 |
-
- git branch
命令 |
解析 |
git branch |
查看當前倉庫的分支列表及當前分支 |
git branch -m <oldbranch> <newbranch> |
重命名oldbranch爲newbranch |
git branch -c <oldbranch> <newbranch> |
複製oldbranch並命名爲newbranch |
git branch -d <branch> |
如果該分支已經合併到主分支,刪除branch分支 |
git branch -D <branch> |
強制刪除branch分支 |
git branch -m <oldname> <newname> git branch -m <newname> |
爲分支改名,第一種適用於給任意分支改名,第二種適用於給當前分支改名 |
git branch -vv |
查看當前分支與遠程跟蹤分支的關係 |
git branch -a |
查看所有分支,包括本地和遠程分支 |
git branch -r |
查看所有遠程分支 |
git branch --set-upstream-to [remote]/[branch] |
將當前本地分支與給定的遠端分支進行關聯,remote是遠端倉庫名,branch是遠端分支名,可以含/符號,例如 git branch --set-upstream-to origin/feature/xxxx |
-
- git add
命令 |
解析 |
git add . |
將當前分支下所有新建的未暫存的文件進行暫存,即狀態變更爲stage |
git add <target> |
將指定的目標進行添加暫存,這裏的<target>既可以是文件,也可以是目錄 |
git add -f <file> |
強制添加文件到stage,會繞過忽略規則 |
-
- git commit
命令 |
解析 |
git commit -m “<description>” |
將當前分支工作目錄下所有狀態爲暫存的文件提交到該分支的版本庫中 |
git commit --amend |
修改最近一次的提交記錄 |
git commit -a |
提交所有的變動文件,相當於git add .和git commit的組合操作,但需要注意的是,這並不會暫存也不會提交新增的文件 |
-
- git fetch
命令 |
解析 |
git fetch <origin> <branch> |
從遠端倉庫下載代碼到本地倉庫對應的分支,此操作僅更新本地的版本庫,而不會影響工作目錄與暫存區 |
git fetch <origin> <branch>:<newbranch> |
從遠端倉庫的<branch>分支下載代碼到本地倉庫新建的<newbranch>分支 |
在更新時爲了安全起見,可以按如下操作:
git fetch origin master:tmp //從遠程倉庫master分支獲取最新,在本地建立tmp分支
git diff tmp //將當前分支和tmp進行對比
git merge tmp //合併tmp分支到當前分支
git branch -d temp //刪除臨時分支
或者:
git fetch orgin master //將遠程倉庫的master分支下載到本地當前branch中
git log -p master ..origin/master//比較本地的master分支和origin/master分支
git merge origin/master //進行合併
-
- git pull
命令 |
解析 |
git pull |
將遠端倉庫對應分支下載到本地,並直接merge到本地,相當於上述git fetch組合操作組合,因此此操作有一定風險,建議使用fetch,確認無誤後再進行merge |
-
- git merge
命令 |
解析 |
git merge <targetbranch> -m <description> |
在本地版本庫中將當前分支與目標分支合併 |
git merge <remote>/<branch> |
將本地分支與遠程倉庫中指定分支合併,但需要注意的是在使用此命令時,需要先執行下pull命令保證當前代碼是最新的,否則無法正常合併,因爲git在本地有一份各分支的清單,不pull更新的話它檢測到本地目標版本號是舊的,所以直接提示代碼爲最新 |
-
- git push
命令 |
解析 |
git push --set-upstream <remote> <branch> |
將<branch>分支添加到<remote>遠端對應倉庫 |
git push |
將本地版本庫中的變動提交到遠端對應倉庫對應分支中 |
git push [remote] [localbranch]:[remotebranch] |
將本地分支<localbranch>推送到遠端<remote>的<remotebranch>分支上,如果遠端<remotebranch>不存在,則會自動創建該分支,需要注意的是此操作不會將本地分支與遠端分支進行關聯 |
-
- git diff
命令 |
解析 |
git diff <branch> |
將當前分支和目標分支進行對比 |
-
-
- 對比結果分析
-
---代表源文件
+++代表目標文件
通常working area的文件都是被當作目標文件來看待。
-開頭的行,是隻出現在源文件中的行
+開頭的行,是隻出現在目標文件中的行
空格開頭的行,是源文件和目標文件中都出現的行
差異按照差異小結進行組織,每個差異小結的第一行都是定位語句,由@@開頭,@@結尾。
參考:https://blog.csdn.net/xx326664162/article/details/50926001
-
- git checkout
命令 |
解析 |
git checkout <branch> |
將當前工作區切換到<branch>分支,需要注意的是,此過程會導致未暫存的變動文件丟失 |
git checkout -- <file> |
將<file>文件切換到工作區中的版本 |
git checkout <id> -- <file> |
將<file>文件切換到某id版本 |
git checkout . |
用暫存區全部的文件替換工作區的文件 |
git checkout HEAD . git checkout HEAD <file> |
用 HEAD 指向分支中的全部或者部分文件替換暫存區和以及工作區中的文件 |
git checkout -b <newbranch> <remote>/<frombranch> |
從remote遠端的frombranch分支拉取到本地並創建一個新的分支newbranch,並切換到該分支 |
-
- git reset
命令 |
解析 |
git reset HEAD |
暫存區的目錄樹會被重寫,被head指向的分支目錄樹所替換,但是工作區不受影響,即上次commit的所有文件都會被取消提交 |
git reset <file> |
將某文件從暫存區移除,即取消提交某文件 |
-
- git clean
命令 |
解析 |
git clean -f |
強制清除所有未暫存的文件 |
git clean -fd |
強制清除所有未暫存的文件,包括目錄 |
git clean -nfd |
預覽即將清除的文件與目錄 |
- 忽略文件
對於一些我們不需要提交的文件,每次提交時都會對我們的提交內容造成干擾,git提供了忽略機制,使用起來也非常簡單,只需要在倉庫目錄下(與.git目錄同級)創建.gitignore文件,在文件中配置忽略規則即可。
簡單的忽略規則示例:
忽略目錄:
*/target
*/.idea
忽略文件:
*.iml
- 查詢代碼量
- 查詢個人時間段內代碼量
git log --author="dongrui" --since=2020-01-01 --until=2020-01-31 --pretty=tformat: --numstat | awk '{ add += $1; subs += $2; loc += $1 - $2 } END { printf "added lines: %s, removed lines: %s, total lines: %s\n", add, subs, loc }' -
-
- 查詢個人時間段內提交次數
git log --author=dongrui --since="2014-07-01" --until=2014-08-31 --no-merges | grep -e 'commit [a-zA-Z0-9]*' | wc -l
-
- 查詢時間段內所有人提交次數
git log --since=2020-03-01 --until=2020-03-31 | grep "^Author: " | awk '{print $2}' | sort | uniq -c | sort -k1,1nr
-
- 查詢郵件格式賬戶時間段內提交代碼量,升序排列
git log --format='%ae' | sort -u | while read email; do echo -en "$email\t"; git log --author="$email" --since="2020-03-01" --until="2020-03-31" --pretty=tformat: --numstat --stat | grep -E ".java|.xml|.yml|.sql" | awk '{ add += $1; subs += $2; loc += $1 - $2 } END { printf "added lines: %s, removed lines: %s, total lines: %s\n", add, subs, loc }' -; done
- 踩坑記錄
- 賬號切換問題
在使用中切換賬號後發現無法正常使用,clone和fetch出現報錯,報錯信息提示CAPTCHA required
經過查找,發現是因爲之前用其它賬號登陸過,windows會記錄下該網址的憑證,而之前的用戶修改了密碼,所以導致了上述錯誤,然後就在git中修改賬戶密碼,但是無論在git中如何操作,都無法正常使用,最後發現是因爲windows憑證不會被隨git的用戶密碼改變,所以如果要切換賬號,需要將這裏的windows憑證刪除。
控制面板-->用戶帳戶-->憑據管理器,找到對應網址的憑據然後刪除。
感謝這個老外~~