本文爲歷時1年多整理的吐血原創,請勿原文轉載,引用請貼出出處。
一、項目使用
1.1 git 從遠程服務器更新本地項目
從遠程服務器上更新別人上傳的文件
1.使用git fetch更新,相當於是從遠程獲取最新版本到本地,不會自動merge
git fetch origin master
git log -p master..origin/master
git merge origin/master
首先從遠程的origin的master主分支下載最新的版本到origin/master分支上
然後比較本地的master分支和origin/master分支的差別
最後進行合併
上述過程其實可以用以下更清晰的方式來進行:
git fetch origin master:tmp
git diff tmp
git merge tmp
從遠程獲取最新的版本到本地的tmp分支
之後再進行比較合併
2.使用git pull 更新,相當於是從遠程獲取最新版本並merge到本地
git pull origin master
上述命令其實相當於git fetch 和 git merge
在實際使用中,git fetch更安全一些
因爲在merge前,我們可以查看更新情況,然後再決定是否合併
3. idea下的操作和vs工程文件的更新
idea打開源碼目錄後,記得,exclude build等無關目錄。
使用idea中集成的git插件,同步遠程倉庫的最新修改到本地。
在上面操作完後,直接使用cmake-gui選中源碼,選中build目錄。然後config, generate重新生成下.sln(防止新生成的文件,加載不上去)。
打開的.sln文件,將會發現,書籤還是有效的。
1.2 撤銷已經commit但是還沒有push的操作(2020.4.23)
找到之前提交的git commit的 commit_id, commit_id爲類似於“51ec2ec6926822435edddd0b9680f3d8329c137b”的一組字符串。
git log
找到想要撤銷的commit_id。選擇要commit_id時,此時如果需要恢復到 test2的話,則test2之後,到第一個"update 2020.04"之間的更新都將消失。所以,如果兩次"update 2020.04"的有問題,需要恢復到第一次"update 2020.04"commit之前的狀態時,則此處需要選中第一個"update 2020.04"的commit_id。
否則,選錯了commit_id,將會讓你看到更新的大規模丟失。不過不要慌亂,還是可以恢復的,但如果你刪除了本地的.git文件夾(任何時候都不要刪除它),那就回天乏力了。
git reset --soft commit_id
完成撤銷,同時將代碼恢復到前commit_id 對應的版本,強制回滾到之前的版本。
git reset commit_id
完成撤銷,停留在當前版本,不對代碼修改進行撤銷,可以直接通過git commit重新提交對本地代碼的修改。
執行 git log 查看,commit提交已撤銷。
rehead的幾種區別
1.3 刪除遠程的文件或文件夾
原因有很多,如錯傳了保密的文件到git,需要刪除,但希望本地保留。或者由於本地修改了文件夾大全名大小寫的原因,同步到git上並不區分大小寫,造成了一些文件同步不了,所以要先把git遠程庫上文件夾刪除掉,然後再重新同步。如,我把dirs裏的全部移除,但是本地文件還保留。
git rm -r -n --cached */dirs/\* # -n:加上這個參數,執行命令時,是不會刪除任何文件,而是展示此命令要刪除的文件列表預覽。 git rm -r --cached */dirs/\* # 最終執行命令. git commit -m "移除dirs目錄下所有文件" # 提交 git push origin master # 提交到遠程服務器 |
1.4 錯add的撤銷
git add 添加 多餘文件
這樣的錯誤是由於, 有的時候 可能
git add . (空格+ 點) 表示當前目錄所有文件,不小心就會提交其他文件
git add 如果添加了錯誤的文件的話
撤銷操作
git status 先看一下add 中的文件
git reset HEAD 如果後面什麼都不跟的話 就是上一次add 裏面的全部撤銷了
git reset HEAD XXX/XXX/XXX.java 就是對某個文件進行撤銷了
1.5 撤銷push
1) 執行 git log查看日誌,獲取需要回退的版本號
2) 執行 git reset –-soft <版本號> ,如 git reset --soft 4f5e9a90edeadcc45d85f43bd861a837fa7ce4c7 ,重置至指定版本的提交,達到撤銷提交的目的
然後執行 git log 查看
此時,已重置至指定版本的提交,log中已經沒有了需要撤銷的提交
git log後,需要退出vim,按Q即可。
git reset 命令分爲兩種: git reset –-soft 與 git reset –-hard ,區別是:
前者表示只是改變了HEAD的指向,本地代碼不會變化,我們使用git status依然可以看到,同時也可以git commit提交。後者直接回改變本地源碼,不僅僅指向變化了,代碼也回到了那個版本時的代碼。
3) 執行 git push origin 分支名 –-force ,強制提交當前版本號。
如,
git push origin master --force
一定要force,否則下次修改提交後,提示會讓你merge,這樣你要回退遠程服務器上的v1_3_1的提交就失敗了。
至此,撤銷push提交完成。
完整的回退操作過程:
git push origin master --force
此時,刷新下idea,將會發現,之前v1.3.1提交的修改,又返回去了,而且v1.3.1之後的修改,也沒有消失。
1.6 git rebase, cherry-pick
git cherry-pick
git cherry-pick 可以選擇某一個分支中的一個或幾個commit(s)來進行操作。例如,假設我 們有個穩定版本的分支,叫v2.0,另外還有個開發版本的分支v3.0,我們不能直接把兩個分支合併,這樣會導致穩定版本混亂,但是又想增加一個v3.0 中的功能到v2.0中,這裏就可以使用cherry-pick了。
# 先在v3.0中查看要合併的commit的commit id
git log
# 假設是 commit f79b0b1ffe445cab6e531260743fa4e08fb4048b
# 切到v2.0中
git check v2.0
# 合併commit
git cherry-pick f79b0b1ffe445cab6e531260743fa4e08fb4048b
git merge是用來合併兩個分支的。
# 將b分支合併到當前分支
git merge b
假設現在有兩zd個分支 A B
1) 在B分支上執行內 git merge A 後 A就被合到B上了
2) 在B分支上執行 git rebase A 後,效果與merge是一樣的,但是 A就沒有了,兩個分容支就合在一起了。
git rebase有點類似git merge,但是兩者又有不同,打個比方,你有兩個抽屜A和B,裏面都裝了衣服,現在想把B中的衣服放到A中,git merge是那種橫衝直撞型的,拿起B就倒入A裏面,如果滿了(衝突)再一併整e799bee5baa6e4b893e5b19e31333337373566理;而git rebase就很持家了,它會一件一件的從B往A中加,會根據一開始放入的時間順序的來加,如果滿了你可以處理這一件,你可以繼續加,或者跳過這一件,又 或者不加了,把A還原。所以merge適合那種比較瑣碎的,簡單的合併,系統級的合併還是用rebase吧。
專業的區別請移步到這裏合併和衍合
# 合併b
git rebase b
# 處理完衝突繼續合併
git rebase –continue
# 跳過
git rebase –skip
# 取消合併
git rebase –abort
1.7 git stash
應用場景:
1 當正在dev分支上開發某個項目,這時項目中出現一個bug,需要緊急修復,但是正在開發的內容只是完成一半,還不想提交,這時可以用git stash命令將修改的內容保存至堆棧區,然後順利切換到hotfix分支進行bug修復,修復完成後,再次切回到dev分支,從堆棧中恢復剛剛保存的內容。
2 由於疏忽,本應該在dev分支開發的內容,卻在master上進行了開發,需要重新切回到dev分支上進行開發,可以用git stash將內容保存至堆棧中,切回到dev分支後,再次恢復內容即可。
總的來說,git stash命令的作用就是將目前還不想提交的但是已經修改的內容進行保存至堆棧中,後續可以在某個分支上恢復出堆棧中的內容。這也就是說,stash中的內容不僅僅可以恢復到原先開發的分支,也可以恢復到其他任意指定的分支上。git stash作用的範圍包括工作區和暫存區中的內容,也就是說沒有提交的內容都會保存至堆棧中。
具體,參考0423 git stach的使用
1.8 遷移代碼到另一個遠程git倉庫
不保留log等提交的記錄的遷移就不說了,soeasy!
目標:把A倉庫的代碼遷移到B倉庫並且保存所有的git log,B倉庫已經存在了哦,哪怕是個空倉庫。
再說這個之前先說點其他。在使用git的時候我們可能見到這樣的命令。不想看解說想直接看步驟的往下翻
git pull origin master //拉取遠程master分支的代碼
git push origin master //把代碼推到遠程master分支上去
有沒有人好奇爲什麼是origin,而不是其他名字,比如git pull orginal master或者git pull origin2 master;
解答上面的問題很簡單,請在你的工程中輸入
git remote
發現了什麼呢?默認就有一個origin,代表遠程倉庫。origin是有地址,地址就是當前倉庫的git地址,是個url哦。所以爲什麼git push origin master就自動相應的推到的遠程倉庫的master分支了。
下面是正確的操作步驟 (看準情況分類很重要,就兩種)
不管哪種情況請從情況1開始看哈哈:
情況1:
B倉庫是一個空倉庫,除了默認的master分支,沒有任何分支。把A的branch1,branch2,branch3...依次遷入B,B也就有branch1,branch2,branch3,
- 進入A工程
- git remote
原因:看下當前遠程倉庫有啥名字,然後取個嶄新的、不重複的名字,名字是過渡,不必糾結取啥名字因爲名字不是關鍵綁定的url纔是,看下一步。這裏取名origin2
- git remote add origin2(這替換你自己心目中的名字) master
不糾結照抄這就話
- git remote set-url origin2 [email protected]:B.git
原因:後面的B倉庫地址url纔是關鍵,origin2只是過渡,百人百種起法
- 進入A工程的branch1分支上
- git pull
原因:拉取一下最新代碼
- git checkout -b branchB1
原因:branchB1是基於A工程branch1開的新分支,代碼跟A工程branch1一毛一樣,但是這個名字branchB1非常重要,非常重要,原因只有一個:這個分支會被推到B工程,結果就是B工程下面就有這個分支。所以你懂的,萬一你的B工程下面已經有了該分支名字,你這個做了好多工作的branchB1是根本推不上去的,是不是很瘋狂
- git push origin2
結果:這一步能不能成功就看上一步,不多說,就看你取名字瞎不瞎
如果上面的結束,說明已經成功遷移出一個分支了。常見問題:
疑問1:問其他的分支怎麼做,請重複
- 進入A工程的branch2分支上
- git pull
- git checkout -b branchB2
- git push origin2
branch2 變成branchB2然後被推到B倉庫
疑問2:你還問我第三個分支怎麼遷移,不解釋啦實在不行哎我還能說啥。
疑問3: 我打眼一看B工程中的分支名字都是branchB1,branchB2....怎麼破,
改分支的名字直接登陸git.hub.com,打開工程你會看到branches這個,點進去可以修改.至於改名字,代碼都遷移過去了,改個名字還很遠嗎
情況2:
B倉庫不是一個空倉庫,裏面各種各樣亂七八糟的分支。把A的branch1,branch2,branch3...依次遷入B,B也就有branch1,branch2,branch3,
呃呃呃呃呃,
步驟跟上面一毛一樣,能不能推成功,就看你起名字的功夫了。什麼名字,就是你最後要推到B工程上去的分支名字,注意部分就是上面疑問1的地方
1.9 git 下載項目(zip)後,關聯遠程倉庫 (事後關聯)
前期網速不佳,下載了zip,期間又修改了源碼,後期需要重新關聯遠程倉庫,拉取新的修改。
方案1
- Grab the .git directory by cloning a bare
repository
$ mkdir repo
$ git clone --bare http://github/user/repo repo - Make the .git directory and move the cloned
files
$ mkdir repo/.git
$ mv repo/* repo/.git - Unzip the
repository
$ unzip repo.zip - Re-initialize the
repository
$ cd repo
$ git init - Verify you're
sync'ed
$ git pull - Reset the HEAD to
clean up the status
$ git reset HEAD
方案2 (推薦)
unzip <repo>.zipgit
cd <repo>
git init
git add .
// git commit -m "my modify" // 如果自己修改了部分,可以這樣先提交自己的修改
// 如果自己沒有修改,直接就git clone好了,不要使用本方案2了。
git remote add origin https://github.com/<user>/<repo>.git
git remote update
git checkout master
Just make sure to replace <user> & <repo> with your github user name and your repo name ;)
方案3
第一步: 初始化空的git本地倉庫
git init
第二步:添加所有文件
git add .
第三步:提交所有文件到本地倉庫
git commit -m "xxx"
第四步:關聯遠程倉庫
git remote add origin “遠程倉庫”
第五步:本地項目推送遠程倉庫
git push -u origin master
五步之後即可完成關聯
1.10 項目的在線依賴庫
下載
當git clone下來了一個項目,但是後來cmake的時候,發現有些在線依賴庫沒有被下載下來。如何補救?
cd 到相應的第三方庫目錄下,然後執行:
git submodule update --init --recursive
Cheetah@Cheetah-PC MINGW64 / $ cd /e/Projs/algs/cc/CloudCompare/extern/CCCoreLib/
Cheetah@Cheetah-PC MINGW64 /e/Projs/algs/cc/CloudCompare/extern/CCCoreLib (master) $ git submodule update --init --recursive Submodule 'extern/CCCoreLib' (https://github.com/CloudCompare/CCCoreLib.git) registered for path './' Submodule 'plugins/core/IO/qE57IO/extern/libE57Format' (https://github.com/asmaloney/libE57Format) registered for path '../../plugins/core/IO/qE57IO/extern/libE57Format' Submodule 'plugins/core/Standard/qPoissonRecon/PoissonReconLib' (https://github.com/cloudcompare/PoissonRecon) registered for path '../../plugins/core/Standard/qPoissonRecon/PoissonReconLib' Cloning into 'E:/Projs/algs/cc/CloudCompare/extern/CCCoreLib'... Cloning into 'E:/Projs/algs/cc/CloudCompare/plugins/core/IO/qE57IO/extern/libE57Format'... Cloning into 'E:/Projs/algs/cc/CloudCompare/plugins/core/Standard/qPoissonRecon/PoissonReconLib'... Submodule path './': checked out 'bb858fa089134e008750e0d1e02f7dd3fd87412c' Submodule path '../../plugins/core/IO/qE57IO/extern/libE57Format': checked out '14f6a67cf98485189cfd154bc42081d38e480b9d' Submodule path '../../plugins/core/Standard/qPoissonRecon/PoissonReconLib': checked out '134fb831764dd5ebd53616e83992f0060e4b09ce'
Cheetah@Cheetah-PC MINGW64 /e/Projs/algs/cc/CloudCompare/extern/CCCoreLib ((bb858fa...)) |
或者,事先已經發現缺失了某個庫,git clone時使用如下命令操作。
git clone --recursive https://github.com/influxdata/influxdb-java.git
添加第三方庫的依賴
真正項目開發過程中避免不了要使用第三方的庫或模塊,或者自己開發過的模塊需要引用到其他業務裏面,避免重複開發,簡單的辦法把模塊倉庫當成主項目的子倉庫。
git submodule git submodule add git://xxxxx.git findername git submodule status git submodule update |
1.11 使fork項目與源項目保持一致方法
github上經常乾的一件事情是看到好的項目,總會fork到自己的項目列表裏,但是源項目如果更新了,怎麼同步到我們自己的fork項目呢?
操作如下:
- 先clone自己的fork項目到本地工程目錄, git clone [email protected]:riqi/{project}.git
- 進入該項目目錄,添加別名並指向源項目,git remote add {project} [email protected]:{group}/{project}.git
- 拉取源項目的master主幹代碼並自動合併到本地fork的master主幹代碼,git pull {project} master
- 合併成功後,將合併後的代碼推送到自己的fork項目master主幹代碼,git push
以上4個步驟,即可輕鬆更新自己的fork項目同源項目master主幹代碼保持一致!
1.12 切換遠程倉庫地址
git remote-v 顯示所有的遠程地址
或,git remote 查看所有遠程倉庫, git
remote xxx 查看指定遠程倉庫地址
# git remote rm origin
# 方法1 (推薦)
git remote add origin2
[email protected]:tyyking/sharding-sphere-demo.git
# 方法2 (直接覆蓋原來的orign,慎用)
git remote set-url [email protected]:tyyking/sharding-sphere-demo.git
# 方法3
進入git_test/.git,修改config中的【remote "origin"】裏的url。
Git check某個分支
git clone -b devel https://github.com/cnr-isti-vclab/vcglib.git vcg
1.13 合併分支
情況是這樣的,我之前將本地的代碼,commit到了master。但是遠程是devel分支(默認分支)。我執行 1.9 小節的方案2時,checkout devel後,發現之前的修改都x消失掉了。
所以,我可以chechout master,可以看到自己的修改,但是無法和遠程origin/devel關聯了。所以,我再checkout devel默認分支。然後,執行merge:
git merge --allow-unrelated-histories master
注意:沒有後面的 --allow … 的內容,將提示“ fatal: 拒絕合併無關的歷史”。
1.14 在線fork的項目更新
爲什麼不在本地操作,而直接在github上操作,主要是因爲自己的更改的部分小,無需下載到本地,再pull到自己的origin maste分支上。
(1) 打開fork 過來的項目, 點擊new pull request
(2)在進入的界面, 後進行將左邊的設置爲你自己的倉庫, fork 過來的源在右邊。
接下來, 將其展示出可以調整狀態: 右邊改爲源fork地址
就會出現變更數據
點擊create pull request
1.15 項目分支管理
命令 |
|
得到結果 |
說明 |
git branch |
當前所有分支的一個列表 |
$ git branch |
注意 master 分支前的 * 字符:它代表現在檢出的那一個分支(也就是說,當前 HEAD 指針所指向的分支)。 這意味着如果在這時候提交,master 分支將會隨着新的工作向前移動。 |
git branch -v |
查看每一個分支的最後一次提交 |
$ git branch -v |
|
git branch --merged |
|
|
--merged 與 --no-merged 這兩個有用的選項可以過濾這個列表中已經合併或尚未合併到當前分支的分支。 如果要查看哪些分支已經合併到當前分支,可以運行 git branch --merged。 |
git branch --no-merged |
|
|
這裏顯示了其他分支。 因爲它包含了還未合併的工作,嘗試使用 git branch -d 命令刪除它時會失敗。果真的想要刪除分支並丟掉那些工作,如同幫助信息裏所指出的,可以使用 -D 選項強制刪除它。 |
git branch -r |
查看遠程分支 |
$ git branch -r origin/HEAD -> origin/master origin/feature/IOS_visualtrack origin/feature/android_visualtrack origin/master |
|
git branch -a |
查看所有分支 |
|
git branch -r 無法獲取遠程分支,ui可以看見分支但是git 命令無法查看 原因 git branch -a 這條命令並沒有每一次都從遠程更新倉庫信息,我們可以手動更新一下。 git fetch origin git branch -a |
git checkout -b myRelease origin/Release |
切換遠程分支 |
$ git branch -a * master remotes/origin/HEAD -> origin/master remotes/origin/Release remotes/origin/master
$ git checkout -b myRelease origin/Release Branch myRelease set up to track remote branch Release from origin. Switched to a new branch 'myRelease' |
作用是checkout遠程的Release分支,在本地起名爲 myRelease分支,並切換到本地的myRelase分支。 |
git merge branch_xxxx |
合併分支 |
$: git checkout master $: git merge issue1234 Merge made by recursive. README | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) |
如果,需要將dev分支合併到master上,則需要首先將當前的分支切換到master,合併後,別忘git push |
git branch new_branch_xxxx |
新建一個分支 |
|
如果newbranch名字分支已經存在,則需要使用-M強制重命名,否則,使用-m進行重命名。 |
git branch -m | -M oldbranch newbranch |
重命名分支 |
|
|
git branch -d | -D branchname
git branch -d -r remote_branchname |
刪除本地、遠程分支 |
|
|
git push origin local_new_branch |
本地新分支推送到遠程 |
|
這裏的含義是將local_new_branch這個分支提交到遠程倉庫上面。如果遠程倉庫沒有這個分支,那麼也會新建一個該分支。 |
git push origin local_new_branch:master |
指定提交到遠程倉庫的某個分支上 |
|
|
git pull origin local_new_branch:master |
把遠程倉庫的master與我的local_new_branch分支合併(merge) |
|
如果您使用“git pull master”,含義就是將遠程倉庫的master分支合併下來。如果本地沒有master分支,那麼本地就新建一個master分支 |
1.16 初始化一個新的工程
先在github之類的網站上新建一個工程,不添加任何文件。此時如果想要僅初始化一個dev分支。
可以在本地將該工程git clone下來;
燃後,新建一個readme.md, .gitignore文件
之後commit,push。在push時,若在idea下,填寫push的分支爲dev即可。
1.17 回退遠程git
(1) soft方式回退到遠程某次commit
(2) git push origin dev --force
1.18 Unresolved Conflicts
Can't commit changes due to unresolved conflicts.
Pulling is not possible because you have unmerged files.
hint: Fix them up in the work tree, and then use 'git add/rm <file>'
hint: as appropriate to mark resolution and make a commit.
Exiting because of an unresolved conflict.
git status 查看狀態,解決衝突
git add file
git commit -m "fix
conflict"
git push -f
https://blog.csdn.net/weixin_45785873/article/details/107096827
1.19 TAG 的刪除
Github的Release,是建立在Git的tag上,是對tag的一層封裝。Git的tag只是一個標籤,而Github的Release在Tag的基礎上,還可以包含更多的打包文件,比如可執行文件等。因此,在Github上,刪除了Release後,這個Release對應的tag還存在,還要繼續再刪除一次,這個tag纔會消失。
如何在本地刪除Tag,並push到Github
git tag -d <tagname>
刪除本地tag
git push origin --delete <tagname>
刪除遠端tag
git push origin <tagname>
向遠端推送本地tag
git push origin --tags
向遠端推送本地所有tag
https://www.maixj.net/ict/release-tag-22821
1.20 添加license
https://www.cnblogs.com/chenmingjun/p/8555906.html
1.21 刪除遠程倉庫的文件而不刪除本地文件
在刪除成功後重新提交和push,即可更新遠程倉庫。
git rm -r --cached XXXX
git commit -m "XXXX"
git push -u origin master
注:
在刪除遠程倉庫的文件時,務必重新clone一份,並在這份源碼上操作,不能在最原始的源碼上操作,容易丟失文件。
1.x 其他常用命令
強推
git push -f origin[遠程倉庫名稱] dev[分支名稱]
其它
git diff 顯示暫存區和工作區的差異
git fetch origin 拉取對應的倉庫, 合併到指定的分支(git merge origin/master
git remote add origin [email protected] 在本地倉庫中建立一個與遠程倉庫的別名,以便之後提交代碼而不是每次都要輸入遠程倉庫地址
二、SVN和Git的基本原理
理解git的思想,而不是單純的會使用幾個命令。知其然,更要知其所以然。
三、Git基本操作
3.1 常用命令
3.2 分支操作
常用命令
git branch列出所有本地分支
git branch -r列出所有遠程分支
git branch -a列出所有本地分支和遠程分支
git branch [branch-name]新建一個分支,但依然停留在當前分支
git checkout -b [branch-name]新建一個分支,並切換到該分支
git branch --track [branch] [remote-branch]新建一個分支,與指定的遠程分支建立追蹤關係
git checkout [branch-name]切換到指定分支,並更新工作區
git branch -d [branch-name]刪除分支
git push origin --delete [branch-name]刪除遠程分支
3.3 merge操作
merge命令把不同的分支合併起來。如上圖,在實際開放中,我們可能從master分支中切出一個分支,然後進行開發完成需求,中間經過R3,R4,R5的commit記錄,最後開發完成需要合入master中,這便用到了merge。
git fetch [remote]merge之前先拉一下遠程倉庫最新代碼git merge [branch] 合併指定分支到當前分支
一般在merge之後,會出現conflict,需要針對衝突情況,手動解除衝突。主要是因爲兩個用戶修改了同一文件的同一塊區域。如下圖所示,需要手動解除。
當你在git分支中工作時,你最終必須將該代碼與其他應用程序集成。學習如何使用git merge來實現這一點。
--------------------------------------------------------------------------------------------------
將功能分離到不同的分支對於任何嚴肅的開發人員來說都是至關重要的。通過分離每個功能,錯誤修復或正在運行的實驗,您將避免很多問題並保持開發分支的清潔。
在某個時候,一段代碼會達到你想要將它與項目其餘部分整合的狀態。這是git merge命令進來的地方。
準備合併
假設我們想要將分支修補程序合併 到您的主分支中。
在我們開始之前,您如何確保您已準備好合併您的更改?
檢查您的本地存儲庫是否與來自遠程服務器的最新更改保持一致git fetch。提取完成後,使用該 git checkout master命令。通過執行確保主分支具有最新的更新git pull。簽出到應該接收更改的分支,在我們的情況下是主人。
合併
一旦準備工作完成後,你可以開始與合併 git merge hotfix的命令。
快進合併
一個快進合併時,有之間的線性路徑可以發生分支,我們要合併。如果主服務器沒有發生分離,而不是創建一個新的提交,它只會將主服務器指向修補程序分支的最新提交。所有來自修補程序分支的提交現在都可以在主分支中使用。
然而,如果分支機構已經分化,則快速合併是不可能的。在這種情況下,您想使用三路合併。
三路合併用額外的承諾來將兩個分支聯繫在一起。
測試一下!使用RSpec測試分支創建您自己的項目,同時編輯master中的Controller測試。現在,嘗試合併。
如何處理合並衝突
一個合併衝突,當你試圖合併這兩個兩個分支改變了同一個文件的同一部分出現。發生這種情況時,Git將無法確定要使用哪個版本。
例如,如果該文件example.rb在同一Git存儲庫的不同分支中的相同行上進行了編輯,或者該文件已被刪除,則當您嘗試合併這些分支時,您將收到合併衝突錯誤。在繼續之前,合併衝突必須通過新提交來解決。
合併衝突只會發生在三方合併的情況下。
1.生成 需要解析的文件列表: git status
# On branch master
# You have unmerged paths.
# (fix conflicts and run "git commit")
# Unmerged paths:# (use "git add ..." to mark resolution)
# both modified: example.rb
# no changes added to commit (use "git add" and/or "git commit
-a")
2.當 遇到衝突線時,Git將使用 標記衝突內容兩側的可視指示符編輯受影響文件 的內容。這些可視標記是:
<<<<<<<- 衝突標記,衝突開始於此行之後。=======- 將您的更改與另一個分支中的更改分開。>>>>>>>- 衝突線的結束。
<<<<<<< HEAD(master)
conflicted text from HEAD(master)
=======
conflicted text from hotfix
>>>>>>> hotfix
決定是否僅保留修補程序或主修改,或者寫一個全新的代碼。在合併您的更改之前刪除衝突標記。
當你準備合併時,你所要做的就是在衝突的文件上運行這個 git add命令來告訴他們已經解決了。
提交您的更改git commit以生成合並提交。希望這有助於您更好地瞭解如何合併分支機構並處理衝突。
3.4 rebase操作
rebase又稱爲衍合,是合併的另外一種選擇。
在開始階段,我們處於new分支上,執行git rebase dev,那麼new分支上新的commit都在master分支上重演一遍,最後checkout切換回到new分支。這一點與merge是一樣的,合併前後所處的分支並沒有改變。head依然指向new分支
git rebase dev,通俗的解釋就是new分支想站在dev的肩膀上繼續下去。rebase也需要手動解決衝突。
rebase與merge的區別
現在我們有這樣的兩個分支,test和master,提交如下:
D---E test /A---B---C---F master在master執行git merge test,然後會得到如下結果:
D--------E / \A---B---C---F----G test, master在master執行git rebase test,然後得到如下結果:
A---B---D---E---C'---F' test, master可以看到,merge操作會生成一個新的節點,之前的提交分開顯示。而rebase操作不會生成新的節點,是將兩個分支融合成一個線性的提交。
如果你想要一個乾淨的,沒有merge commit的線性歷史樹,那麼你應該選擇git rebase。如果你想保留完整的歷史記錄,並且想要避免重寫commit history的風險,你應該選擇使用git merge。
3.5 reset
reset命令把當前分支指向另一個位置,並且相應的變動工作區和暫存區。這個命令還是比較危險的。操作時請確保你知道你要做什麼。
git reset —soft [commit]只改變提交點,暫存區和工作目錄的內容都不改變git reset —mixed [commit]改變提交點,同時改變暫存區的內容git reset —hard [commit]暫存區、工作區的內容都會被修改到與提交點完全一致的狀態git reset --hard HEAD讓工作區回到上次提交時的狀態,本地的修改都不要了。
3.6 revert
git revert用一個新提交來消除一個歷史提交所做的任何修改。如上圖,將提交回滾到15df9b6。
revert與reset的區別
git revert是用一次新的commit來回滾之前的commit,git reset是直接刪除指定的commit。在回滾這一操作上看,效果差不多。但是在日後繼續merge以前的老版本時有區別。因爲git revert是用一次逆向的commit“中和”之前的提交,因此日後合併老的branch時,導致這部分改變不會再次出現,減少衝突。但是git reset是之間把某些commit在某個branch上刪除,因而和老的branch再次merge時,這些被回滾的commit應該還會被引入,產生很多衝突。git reset 是把HEAD向後移動了一下,而git revert是HEAD繼續前進,只是新的commit的內容和要revert的內容正好相反,能夠抵消要被revert的內容。分支策略
master主分支應該非常穩定,用來發布新版本,一般情況下不允許在上面工作,工作一般情況下在新建的dev分支上工作,工作完後,比如上要發佈,或者說dev分支代碼穩定後可以合併到主分支master上來。
push
上傳本地倉庫分支到遠程倉庫分支,實現同步。
git push [remote] [branch]上傳本地指定分支到遠程倉庫git push [remote] --force強行推送當前分支到遠程倉庫,即使有衝突。不建議使用git push [remote] --all推送所有分支到遠程倉庫
打標籤操作
Git 支持兩種標籤:輕量標籤(lightweight)與附註標籤(annotated)。
git tag v1.0 //輕量標籤git tag -a tagName -m "my tag" //附註標籤。建議使用後期打標籤
假如你忘記了對某個提交打標籤,可以後期補上
git tag -a v1.2 9fceb02 -m "補打標籤"
將tag同步到遠端倉庫
默認情況下,git push 命令並不會傳送標籤到遠程倉庫服務器上。在創建完標籤後你必須顯式地推送標籤 使用git push origin [tagName]推送單個分支。
git push origin v1.0推送本地所有tag,使用git push origin --tags。
3.7 切換到某個tag
跟分支一樣,可以直接切換到某個tag去。
git checkout v1.0但是注意:這個時候不位於任何分支,處於遊離狀態,可以考慮基於這個tag創建一個分支。
git checkout -b 新分支名 v1.0
3.8 其他命令
git status顯示有變更的文件git log顯示當前分支的版本歷史git diff顯示暫存區和工作區的差異git diff HEAD顯示工作區與當前分支最新commit之間的差異git cherry-pick [commit]選擇一個commit,合併進當前分支
3.9 Git問題解決
員工密碼定期修改後的問題
我們的git倉庫bitbucket密碼是和員工賬號密碼綁定的。我們的員工密碼每兩個月會強制修改一次,導致git密碼校驗失敗。
錯誤顯示:remote error: CAPTCHA required
解決:
1,打開控制面板;
2.點擊打開用戶賬戶;
3.點擊打開憑證管理(windows憑證管理欄)
4.普通憑證下拉打開修改你已存在的git賬號密碼
修改或刪除都可以
回到瀏覽器上把賬戶退出,重新登錄下這一步經常會漏。
放棄本地修改
本地代碼被改亂了。想要放棄重來。分三種情況。
1. 未使用git add 緩存代碼
放棄某個文件的修改注意中間有--git checkout -- filename放棄所有文件修改 git checkout .git checkout .此命令用來放棄掉所有還沒有加入到緩存區(就是 git add 命令)的修改:內容修改與整個文件刪除注意:此命令不會刪除新建的文件,因爲新建的文件還沒加入git管理系統中,所以對git來說是未知,只需手動刪除即可2. 已使用git add 緩存代碼,未使用git commit
使用 git reset HEAD filenamegit reset HEAD filename放棄所有文件修改 git reset HEADgit reset HEAD此命令用來清除 git 對於文件修改的緩存。相當於撤銷 git add 命令所做的工作。在使用本命令後,本地的修改並不會消失,而是回到了第一步1. 未使用git add 緩存代碼,繼續使用用git checkout -- filename,就可以放棄本地修改
3. 已經用 git commit 提交了代碼
使用 git reset --hard HEAD^ 來回退到上一次commit的狀態git reset --hard HEAD^或者回退到任意版本git reset --hard commit id ,使用git log命令查看git提交歷史和commit idgit reset --hard commit id
Git中文件標題顏色變化的含義
綠色,已經加入控制暫未提交
紅色,未加入版本控制
藍色,加入,已提交,有改動
白色,加入,已提交,無改動
灰色:版本控制已忽略文件。
REF:
Git最全總結(全篇),20.3.17
git 從遠程服務器更新本地項目,19.5
一個關於Git合併的教程,18.5
Git撤銷已經commit但是還沒有push的代碼,18.10
git刪除遠程文件夾或文件的方法, 18.12
【git】git add 添加錯文件 撤銷, 18.1
Git撤銷對遠程倉庫的push&commit提交, 18.9
git命令之git merge 和 git rebase的區別,福喜900,
18.2
git stash詳解,18.6
從一個git倉庫遷移代碼到另一個git倉庫(親測有效版), 18.6
git 下載項目(zip)後,關聯遠程倉庫以及所出現的問題(error: 無法推送一些引用到), 20.3
How to clone git repository from its zip, 20.1
用git,clone依賴的庫,19.4
主git倉庫添加依賴第三方git倉庫, 19.6
git 切換遠程倉庫地址,19.1
Git使fork項目與源項目保持一致方法, 15.7
Git使用---fork項目(windows), 18.4
git fatal: 拒絕合併無關的歷史的錯誤解決, 18.1
github fork 別人的項目源作者更新後如何同步更新, 18.5
3.3 Git 分支 - 分支管理,20.5
Git branch使用, 19.5
git branch用法總結,
16.9
idea中安裝git後,代碼顏色代表的含義,
19.11
Github刪除遠程倉庫的文件而不刪除本地文件, 20.7