Git 原理探秘
版本控制系统与 Git
Git 内部原理基础
Git 基本操作
Git 团队协同开发指令
还没push 前可以做的事
Git概念及工作原理总结
Git 内部原理详解
本文档使用 MrDoc 发布
-
+
首页
Git概念及工作原理总结
Git 是分散式版本控制系统。Github 和华为等均使用 Git 作为程式码管理工具。之前在工作中比较常用到的是克隆、程式码提交拉取、解决回合冲突、程式码回滚等。在实际的工作中,可能回合时冲突及版本回退的情况较多,下文将着重介绍这两点。本文不涉及 Git 的安装等,主要以介绍概念及原理为主。 **个人感觉使用 Idea 内建的 git 比通过 Git Bash 使用 Git 命令要方便且易操作。** ## 一、Git 基本概念 1. 工作拷贝(工作目录):用于存放产品开发资料本地工作目录。 2. 索引(Index):用于存放待提交资料的快取区。 3. 本地库:远端库的一个完整的拷贝,包括所有档案的修改记录,分支等。 4. 远端库:本地库 clone 来源。 5. 中心库:远端库的一种,公司级存放某个专案所有产品资料的仓库。 6. 快照(snapshot):版本库某个时间点所有档案集合。 7. 全球版本号(commitID):Git 库的版本号是用过 SHA-1 演算法根据库中的所有内容计算出一个 40 位的杂凑值,这个杂凑值是全球唯一的,基本只要前六位就可以唯一标识了。 8. 档案状态介绍 1. Untracked files:未被跟踪的档案,一般指新新增的档案。 2. Change not staged for commit:已修改的档案,包括 modified 和 deleted 状态。 3. Change to be commit:已缓冲的档案,即已 add 的档案,包括 modified、deleted 和 new file 状态。 4. Nothing to commit:已提交的档案,即已 commit 的档案。 ## 二、Git 概念及基本操作详解 Git 分为工作区、暂存区、本地仓库和远端分支。 ![在这里插入图片描述](https://i.iter01.com/images/753f81bc7bac951bbe1e78a87c8b716065da039d890a78643720a6bb1c73ca30.png) 1、工作区:本地电脑上的某专案工程的程式码资料夹就是工作区。 2、暂存区:工作区有一个隐藏目录.git,这个不算工作区,而是 Git 的版本库。Git 的版本库里存了很多的东西,其中最重要的就是成为 stage(或者叫 index)的暂存区,还有 Git 为我们自动建立的第一个分支 master,以及指向 master 的一个指标叫 HEAD。 ![在这里插入图片描述](https://i.iter01.com/images/35c3e3b74937eb3e0fce743a52bceea397c732eaa7fa3ab8b7d71460245c434f.png) 我们把档案往 Git 版本库里新增的时候是分两步执行的; 第一步是用 git add 把档案新增进去,实际上就是把档案修改新增到暂存区; ![在这里插入图片描述](https://i.iter01.com/images/5fd60da1c93355086212f961d5f2199ff544b0b3aff579a98165d3d06ab96d58.png) 第二步:是用 git commit 提交更改,实际上就是把暂存区的所有内容提交到本地仓库。 ![在这里插入图片描述](https://i.iter01.com/images/ba6dd2fa27f80cfc84b2075fbd685ebdc39635bdfb3340a8caea061c79bc213a.png) 需要提交的档案修改统统放到暂存区,然后一次性提交暂存区的所有修改。 3、本地仓库 本地仓库就是上图的本地版本库,克隆自远端仓库。从下图可以看到,工作区、暂存区、本地仓库都是在本地计算机上的。 4、远端分支 git push 命令能将本地仓库的程式码上传到远端分支,但是必须经过 committer 确认之后才能合入远端分支。托管在网路上的专案仓库,Git 的远端仓库是分散式的,能够极大保证程式码的安全性。 ## 三、使用 Git clone 专案库的两种方式 1. 命令列克隆($git clone + 程式码库地址) 2. 小乌龟(TortoiseGit)克隆 1. 使用命令列 clone 程式码 2. 第一步:复制程式码库地址——copy Address 3. 第二步:开启 Git Bash,输入: git clone + 程式码库地址 4. 第二步:开启 Git Bash,输入: git clone + 程式码库地址 5. 第一步:复制程式码库地址。 6. 第二步:开启想要克隆到的本地资料夹,右键单击,选择“git clone”命令。 7. 第三步:配置好复制地址及目标地址,点选 OK 即可。 ## 四、合并冲突 因为自己的远端 fork 库一般只有自己一个分支(master),即一个人一个仓,所以在自己名下的程式码库基本不会产生冲突。目前产生合并冲突只有两种可能性。 1、原生程式码进行了一些修改,远端 fork 库同步了远端中心库(Merge),然后本地 clone 库从远端 fork 库更新程式码(pull)。 ![在这里插入图片描述](https://i.iter01.com/images/3809db2aa0994d1f4750c5b9363dbc42f3f4a1a7217ab94da226438e69b8a3a5.png) 2、原生程式码进行了一些修改,并成功 push 到远端 fork 库。但是合入远端中心库时,因为其他人比你先合了程式码,你的 fork 库并没有拉取到这个更改。因此在 ISource 上请求合并时,如果你们更改了同样的程式码,就会提示,存在冲突,无法发起合并请求。 ![在这里插入图片描述](https://i.iter01.com/images/c18fdc410e24293cbb1c2fe8c45ef3f7c3a885e902ae7d4d9c19ef2dbb8f65d1.png) ## 五、程式码回滚 git reset 和 git revert 都用来撤销程式码仓库中某些更改。 git reset 在原生程式码库,add 或 commit 以后发现提交的程式码有问题,删除自己个人分支上还没合入主线的提交。用于个人库。 顾名思义,重置分支,将当前的分支重设(reset)到指定的或者 HEAD(如果不显示指定 commit)预设是 HEAD,即最新的一次提交。有三个引数可供选择。 1、–hard 快取区和工作区都同步到你指定的提交,重置档案索引,自指定提交以来在工作区中的任何改变都被丢弃,并将版本库重置为指定提交(commit)。 2、–mixed 快取区同步到你指定的提交,重置档案索引,但是程式码的改动仍留在工作区中,不会被丢弃。并将版本库重置为指定提交(commit)。 3、–soft 工作区、快取区、档案索引都不会改变,仅仅将版本库重置为指定提交(commit)。 其作用域如下图所示: ![在这里插入图片描述](https://i.iter01.com/images/ee8f7f791654360f3451e8e7593ea2db5c2aad563d2045c4fe193d56c376d8fd.png) git revert 程式码已经 push 上库,同时回滚本地和线上程式码到指定版本,用一个新提交来消除一个历史提交所做的任何修改。用于版本库。 1、如果已经 push 到远端 fork 库,reset 删除指定 commit 以后,gitpush 可能导致一大堆冲突,但是 revert 并不会。 2、reset 是在正常的 commit 历史中,删除了指定的 commit,这是 HEAD 是向后移动了,而 revert 是在正常的 commit 历史中再 commit 一次,只不过是反向提交,他的 HEAD 是一直向前的。 3、git revert 也有可能会重写档案。所以,Git 会在你执行 revert 之前要求你提交或者快取你工作目录中的更改。 六、Git 基本语法 | 语法 | 功能说明 | | ------------------------------ | -------------------------------------------------------------------------------------- | | git 克隆 | 克隆版本库 | | git 拉 | 拉回远端版本库的提交 | | git 推送 | 推送至远端版本库 | | 混帐添加 | 新增至暂存区 | | git add -interactive | 互动式新增 | | git 申请 | 应用补丁 | | 去吧 | 应用邮箱格式补丁 | | git 注释 | 同义词,等同于 git blame | | git 平分 | 二分查询 | | 怪罪 | 档案逐行追溯 | | git blame + 档名 | 显示档案的每一行是在哪个版本最后修改 | | git 分支 | 分支管理 | | git cat 文件 | 版本库物件研究工具 | | git 结帐 | 检出到工作区,切换或建立分支 | | git 樱桃-pick | 提交拣选 | | git citool | 图形化提交,相当于 git gui 命令 | | 清理干净 | 清除工作区未跟踪档案 | | git 提交 | 提交 | | 混帐配置 | 查询和修改配置 | | git 描述 | 通过里程碑直观地显示提交 ID | | 混帐差异 | 差异比较 | | 混帐工具 | 呼叫图形化差异比较工具 | | 获取 | 获取远端版本库的提交 | | git 格式-补丁 | 建立邮箱格式的补丁工具 | | git grep | 档案内容搜寻定位工具 | | git gui | 基于 cl/TK 的图形化工具,侧重提交等操作 | | 帮助 | 帮助 | | 混帐初始化 | 版本库初始化 | | git 初始化-db | 同义词,等同于 git init | | 混帐日志 | 显示提交日志 | | git log - - 漂亮 = oneline | 显示每个版本都修改了哪些档案与 git show (commit id),不过每个修改版本都包含了 | | git 合并 | 分支合并 | | git 合并工具 | 图形化冲突解决 | | git mv | 重新命名 | | git push origin HEAD --force | 回退个人远端 | | git rebase | 分支变基 | | git rebase -interactive | 互动式分支变基 | | git reflog | 分支等引用变更记录管理 | | git repo -配置 | 同义词,等同于 git config | | git 重置 | 重置改变分支,“游标”指向 | | git reset --softcommitID | 原生程式码回退到某一版本 | | git rev -解析 | 将各种引用表示法转换为杂凑值等 | | 去还原 | 反转提交 | | 去 rm | 删除档案 | | git 显示 | 显示各种型别的物件 | | git show (提交 id) | 显示某个版本的修改详情 | | git show + 档名 | 显示某个版本的某个档案修改情况 | | git 阶段 | 同义词,等同于 git add | | 混帐藏匿 | 储存和恢复进度 | | 状态 | 显示工作区档案状态 | | 混帐日 | 里程碑管理 | | git whatchanged + 档名 | 显示某个档案的每个版本提交资讯,提交日期,提交人员,版本号,提交备注(没有修改细节) | ## 七、Git 基本操作 1、配置基本资讯 ``` $git config --global user.name XXX $git config --global user.email XXX ``` 2、克隆中心库到本地 ``` $ git clone +中心庫地址 ``` 3、新增和修改档名 ``` $ git add +檔名 注:將需要新增的檔案拷貝到工作目錄或直接建立,此操作只是將需要新增的檔案轉移至快取 區,如果需快取當前目錄下的所有非受控檔案,則可以通過“git add.”命令來完成已在快取區但 不需提交的檔案怎麼辦? $echo “first” >>>first $git add first 提交:$git commit 注:此操作是將所有快取區的修改提交到本地版本庫 ``` ![在这里插入图片描述](https://i.iter01.com/images/401e07d5bf0b5a992bbc9746b4825d62a0a0d7cfd77b25eb37f0a739bfdc7128.png) 4、取消已快取的修改(回退) (1)$ git rest -hard HEAD+ 档名 (2)$ git rest HEAD+ 档名 ``` 注:此操作將修改的檔案從緩衝區內刪除,不影響本地內容 ``` 5、删除档案 ``` $ git rm 檔名 注:此操作只是刪除檔案並將刪除的資訊轉移至快取區,要想刪除庫上的檔案需要執行commit操 作,同樣適用git reset恢復 eg: $ git rm second $ git commit ``` 6、取消本地档案的修改,包括删除的档案 (1)$ git checkout(HEAD/commitID) ``` 注:此操作將取消本地檔案(未提交)已做的但未提交的修改,如果需回退當前目錄下的所有修改 檔案,則可以通過“git checkout .”命令來完成各成。 eg:$ git checkout -first (2) $ git clean -f 注:清除本地未被跟蹤的所有檔案,使用時需要注意是否確定需要清除 ``` 7、重新命名档案或目录 ``` $ git mv 原檔名 新檔名 注:重新命名或者移動本地檔案或目錄,mv後直接到快取區,需要執行commit操作 eg:$ git mv first first_new ``` 8、检视档案状态 ``` 注:檢視本地庫中所有檔案的狀態,包括未受控的、已修改、已快取。衝突檔案的狀態也表現為已 修改的。 ``` 9、比较档案 ``` $ git diff OldcommitID NewcommitID(前6位) 注:比較檔案/目錄下所有檔案修改前後的不同,不加CommitID,則比較本地的與快取或快取的與 庫中最新的。 新新增的檔案使用git diff的時候不能顯示 git diff和 git diff -cached的不同 ``` 10、检视修改日志 ``` $ gitk --all 注:此操作將調出git日誌的圖形化介面,在相關的版本號上右擊選擇“Create new branch” 來建立基於此項的新分支,需要執行Xming $ git log 注:在命令列中檢視log資訊 注意:檢視日誌資訊只能看到本地的修改日誌和已經獲取到本地的遠端修改日誌,不能看到遠端 還沒有獲取到本地的修改日誌。 ``` 11、建立私有分支 ``` $ git branch 分支名 commitID $ git checkout -b 分支名 commitID 注:此操作是基於commitID即某一個全球版本號拉出新分支,如果沒有則基於當前分支的HEAD 拉出新分支。$ git checkout -b +分支名 commitID=$ git branch 分支名commitID + $ git checkout 分支名 ``` 12、合并分支 ``` (1)直接合並$ git merge +分支名 注:此操作是將“分支名”指示的分支合併到當前所在的分支,所以合併前必須切換到目標 分支。 (2)揀選合併 $ git cherry -pick commitID 注:將某次特定提交合併到當前分支,首先合併前必須切換到目標分支。 ``` 13、检视分支 ``` $ git branch 注:檢視當前git庫中的所有分支,“-r”是檢視git庫中對應的遠端分支參照。 ``` 14、检查分支是否合并到当前分支 ``` $ git branch -mergerd 注:檢視已經合併到當前分支的所有分支。 $ git branch -no -merged 注:檢視還沒有合併到當前分支的所有分支。 ``` 15、删除私有分支 ``` $ git branch -d/-D 分支名 注:此操作“-d”刪除分支前會檢查分支中的內容是否都已經合併到其他分支,如果 沒有,則命 令不執行;“-D”不進行檢查,直接刪除分支。 ``` 16、重新命名分支 ``` $ git branch -m oldbranch newbranch 注:此操作是將“oldbranch”分支的名稱改成“newbranch”。如果需要拉出分株,並同時切換到 新分支可以用“git checkout -b branch1 branch2”。 ``` 17、上传修改到远端(fork)库 ``` $ git push 遠端庫名稱 本地分支名稱:遠端分支名稱 注:此操作是將本地庫的修改同步到中心庫,如果本地分支的名稱和遠端分支的名稱相同,則遠 程分支名稱可忽略。 eg:$ git push origin new :new -br ``` 18、更新当前模组 ``` $ git fetch 遠端庫名稱(獲取遠端庫的更新到本地庫) $ git fetch origin $ git merge 遠端庫名稱/分支名稱(將中心庫的更新合併到本地工作目錄中) $ git merge origin/new -br ``` 19、修改提交资讯 ``` $git commit -m “新的提交資訊” -amend 注:此操作只能修改最新的一次提交,之前的提交無法修改。 ``` 20、回退某一历史版本,然后提交到本地库 ``` $ git revert 全球版本號 注:此操作將回退記錄到歷史的某一節點,並作為一次新的提交到庫中。 ``` 21、暂存本地修改 ``` $ git stash 注:此操作是將本地未提交的修改暫存起來,並將檔案狀態恢復到HEAD,如果要恢復暫存的修 改,執行“ git stash pop”即可,非常適合臨時插入的緊急bug修改。 ``` 22、二分法定位错误 ``` $ git bisect start $ git bisect bad CommitID $ git bisect good CommitID 注:此操作用於定位問題引入的點,輸入如上命令後,git會自動切換到中間的狀態,經過測試 輸入測試結果“git bisect good/bad”,重複以上,直接定位出出錯的提交,然後通過 “git bisect reset”退出。 ``` 23、解决冲突 ``` 合併分支或者合併庫上的更新到本地均會產生衝突。Git的衝突產生是由於同一檔案的同一行 內容。 哪些情況會出現衝突:1.修改了同一個檔案的同一行;2.檔案被重新命名為不同的名字;3.在一個 分支上檔案被刪除在另一個分支上該檔案被修改。 ``` 24、变基 ``` $ git rebase 目標分支 原分支 注:此操作將原分支變基到目標分支HEAD上。 ``` ![在这里插入图片描述](https://i.iter01.com/images/f3a91350b17c9dd9fc8720f8a6a1d6dc44c8ba5a0010180bc8fdf638ec9a5ac6.png) 从主专案 pull 拉最新程式码到本地,如果有冲突在本地解决冲突的成本比在合并的时候再解决要低很多,所以建议在合并到主专案之前,先 pull 一下主专案的最新程式码后在提交合并请求。在这里,你可以用“pull”命令把“origin”分支上的修改拉下来,并且和你的修改合并,结果看起来就像一个新的“合并的提交”(merge commit)。但是,如果你想让“mywork”分支历史看起来像没有经历过任何合并一样,你也许可以用 git rebase。 ``` $ git checkout mywork $ git rebase origin 這些命令會把你的“mywork”分支裡的每個提交(commit)取消掉,並且把它們臨時儲存為補 丁(patch)(這些補丁放到“git / rebase”目錄中),然後把“mywork”分支更新到最新的 “origin”分支,最後把儲存的這些補丁應用到“mywork”分支上。 ``` 24、忽略某些档案 ``` 在git倉工作的根目錄下面,建立gitignore檔案,檔案內容如下例項,同樣gitignore檔案也 可以上傳到庫上,這樣每次下載都可以記錄忽略規則,如果將某個已經忽略的檔案新增,使用 $ git add -f檔名即可。 * .a #忽略所有.a結尾的檔案 ! lib.a #但lib.a除外 /TODO #僅僅忽略專案根目錄下的TODO檔案,不包括subdir/TODO build/ #忽略build/目錄下的所有檔案 doc/*.txt #會忽略build/目錄下的所有檔案 doc/*.txt #會忽略doc/notes.txt但不包括 doc/server/arch.txt ``` 25、使用 GUI 图形化操作介面 ``` $ git gui 新增修改,刪除檔案時,可以直接通過“git gui”命令,調出圖形介面,通過“stage changed” 快取檔案(新新增的檔案只能通過git add命令快取),在提交資訊處輸入“提交資訊”,然後 通過“commit” 提交。 ```
追风者
2022年3月3日 00:39
转发文档
收藏文档
上一篇
下一篇
手机扫码
复制链接
手机扫一扫转发分享
复制链接
关于 MrDoc
觅思文档MrDoc
是
州的先生
开发并开源的在线文档系统,其适合作为个人和小型团队的云笔记、文档和知识库管理工具。
如果觅思文档给你或你的团队带来了帮助,欢迎对作者进行一些打赏捐助,这将有力支持作者持续投入精力更新和维护觅思文档,感谢你的捐助!
>>>捐助鸣谢列表
微信
支付宝
QQ
PayPal
Markdown文件
分享
链接
类型
密码
更新密码