什么是git
百度百科:Git(讀音為/gɪt/)是一個開源的分布式版本控制系統,可以有效、高速地處理從很小到非常大的項目版本管理。
git相對svn,有很多優勢,這里就不再贅述,大家網上搜索吧。
git的操作流程是:比如我們在本地對項目做更新操作,到最后推送到遠程倉庫,需要經歷這幾個步驟:
0.在工作區更新項目
1.添加到暫存區(add)
2.提交到本地倉庫(commit)
3.推送到遠程倉庫(push)
git安裝
詳見:https://www.cnblogs.com/UncleYong/p/10767747.html
git基礎命令
雖然有git客戶端,但是建議還是用命令進行操作,因為命令會了,一個簡單的圖形界面客戶端是很easy的,信不信由你。
git --version,查看版本
git init,初始化本地倉庫(創建一個文件夾,進入這個文件夾,執行git init)
新增文件
git status,查看狀態
git add,將文件添加到暫存區
git commit,文件提交到本地倉庫
提示:
git在commit前,需要初始化配置:設置倉庫人員的用戶名和郵箱地址,這一步必不可少(參考:https://www.cnblogs.com/UncleYong/p/6892171.html)
git config --global user.name "uncleyong"
git config --global user.email "168632201@qq.com"
再次執行commit操作
git push,推送到遠程倉庫
因為我們還沒有關聯遠程倉庫,所以暫時不執行
先在遠程倉庫上創建一個項目(如果沒有賬號,可以注冊一個,https://gitee.com)
輸入倉庫名稱,然后保存即可
復制遠程倉庫地址:https://gitee.com/UncleYong/git_test.git
git remote add添加遠程倉庫,origin可以理解為一個別名
推送到遠程倉庫
master表示推送到master分支(主干分支),-f參數,就是表示強制,由於我們創建的是空項目,所以哪怕里面有內容,也會被覆蓋掉(所以,這個參數要慎用)
輸入賬號
輸入密碼(也可以配置ssh通信方式,這樣可以不用每次都輸入密碼:https://www.cnblogs.com/UncleYong/p/6891958.html)
推送成功
訪問:https://gitee.com/UncleYong/git_test
可以看到,剛剛新增的test.txt文件已經被推送到遠程倉庫
但是,通常,項目不是我們創建的,那么:
如果我們本地沒有這個項目,我們就要先把項目拉到本地,git clone,做了更新后,再走上面的流程
如果我們本地已經有這個項目,但是可能不是最新了,比如你的同事往遠處倉庫提交了代碼,此時,你本地的也做了修改,但是還沒提交,但是你要把遠程的拉下來,
操作方式一:git pull,會把你做的修改覆蓋掉(git pull = git fetch + git merge),所以不推薦,除非你不想保留你的修改
操作方式二:先git fetch,然后git merge將遠程的變更合並到本地倉庫(下面的分支合並詳細講解)。
git提交更改
克隆空項目,從頭開始
test2.txt提交到暫存區
git reset HEAD 文件名,移除提交到暫存區的文件
git reset HEAD^ 或者 commitid,取消上一次的提交
把之前的提交了
兩次提交記錄
變成一次提交記錄了
把上次的提交了
git reset --soft HEAD^:回到上次提交前的狀態,也就是暫存區的狀態
第二次提交沒了,但是文件在暫存區
下面結果說明,執行git reset --soft后,工作區和暫存區的內容不會改變
修改提交信息,再次提交記錄
另外,還有下面兩個,大家自己實踐吧。
git reset --mixed (默認選項)將HEAD指向指定的提交,暫存區的內容隨之改變,工作區內容不變
git reset --hard 將HEAD指向指定的提交,暫存區跟工作區都會改變
把之前的提交了
git reset --hard HEAD^
git分支
每個項目,一般有多個分支,比如master(主干分支)、開發分支、測試分支、生產bug分支等等,一個分支不受其它分支的影響,
但是,分支越多,后期合並分支的成本越大,所以,不要隨便創建不必要的分支。
創建分支:git branch 分支名,分支名不要包含特殊符號,比如*,/,等等,要見其知意,另外,還可以創建並切換分支:git checkout -b 分支名
查看本地所有分支:git branch,分支前面有*號的表示該分支為當前所在分支
修改本地分支名:git branch -m 舊分支名 新分支名
切換分支:git checkout 分支名
刪除本地分支:git branch -d 分支名,但是不能刪除當前所在的分支
切換到master再刪除
其它
查看本地所有分支:git branch 查看遠程所有分支:git branch -r 查看本地和遠程的所有分支:git branch -a 刪除遠程分支:git push origin --delete <branchname> 重命名本地分支:git branch -m <oldbranch> <newbranch> 重命名遠程分支:先刪除遠程待修改分支,然后push本地新分支到遠程服務器 git中一些選項解釋: -d --delete:刪除 -D --delete --force的快捷鍵 -f --force:強制 -m --move:移動或重命名 -M --move --force的快捷鍵 -r --remote:遠程 -a --all:所有
從主干分支拉取新分支開發
從master主干拉取一個新分支,需要先切換到master分支,並且更新到最新,然后創建分支並且關聯遠程倉庫
HEAD文件記錄了當前分支
HEAD文件內容:
創建新分支
HEAD文件內容:
可以修改內容后再push,但是最好先把初始分支push到遠程倉庫
git push --set-upstream origin dev01
拉取指定分支
git clone -b dev01 https://gitee.com/yncleyong/git_test.git
拉取所有分支,先clone,再fetch
先克隆master,再fetch
克隆master
git clone git@gitee.com:UncleYong/my_rf_no_open.git
或者:
git clone -b master git@gitee.com:UncleYong/my_rf_no_open.git
cd my_rf_no_open/
git clone git@gitee.com:UncleYong/my_rf_no_open.git dev01
會在 my_rf_no_open/ 目錄下生成一個文件夾dev01,顯然是不對的
git pull git@gitee.com:UncleYong/my_rf_no_open.git dev01
提示合並,顯然用pull不對
git fetch git@gitee.com:UncleYong/my_rf_no_open.git dev01
或者git fetch origin dev01
內容是master
內容是
先克隆非master,再fetch
git clone -b master git@gitee.com:UncleYong/my_rf_no_open.git
git fetch git@gitee.com:UncleYong/my_rf_no_open.git master
幾個git分支切換的問題
問題一
git clean -d -fx,表示刪除一些沒有git add的文件; git clean 參數 -n 顯示將要刪除的文件和目錄 -x -----刪除忽略文件已經對git來說不識別的文件 -d -----刪除未被添加到git的路徑中的文件 -f -----強制運行
問題二:
git log
用於查看提交歷史(commit的記錄),顯示的順序是由近到遠
顯示的log的含義:
commit id,每個id都是唯一的
Author,初始化時候的配置信息,作者及郵箱
Date,提交日期
xxx,commit -m的提交說明
查看最近n次的提交:git log -n,n是數字
查看指定作者的提交,如果沒有,就顯示空:git log --author xxx
概要顯示:git log --oneline
git log --graph,一條線串聯整個提交歷史
顯示最近n次提交的不差異:git log -p -n,n是數字
git diff
克隆空項目,從頭開始
比較工作區和暫存區的差異(如果暫存區沒有,就和當前分支本地倉庫比較):git diff
比較暫存區和工作區的差異:git diff --cached
比較工作區和當前分支本地倉庫的差異:git diff HEAD,HEAD是指向當前分支的指針
新增文件
如果暫存區和當前分支本地倉庫都沒內容,執行git diff,結果就為空
提交到本地倉庫
下面執行的git diff結果為空,因為工作區為空
修改文件
上面修改后,不add
結果說明:如果暫存區沒有內容,但是當前分支本地倉庫有內容,執行git diff,是工作區和本地倉庫對比,
add后,git diff沒有結果,因為工作區為空
下圖表示暫存和當前分支本地倉庫對比
再次修改
上面修改后,不add
下面執行結果說明:
如果暫存區有內容,不管當前分支本地倉庫是否有內容,執行git diff,是工作區和暫存區對比,
如果暫存區沒有內容,但是當前分支本地倉庫有內容,執行git diff,是工作區和本地倉庫對比,
工作區和當前分支本地倉庫對比
把上面的都提交了
查看當前分支跟指定的分支的差異:git diff 分支名
創建並切換到test分支
然后修改文件
和master分支比較
查看兩個指定分支(已提交的)的差異(后者和前者的差異):git diff 分支名1 分支名2
提交前,沒有輸出結果
提交后,有輸出結果
查看指定文件的差異(比較工作區和暫存區):git diff 文件名
修改
列出兩個歷史提交的差異(后者與前者相比):git diff commitid1 commitid2
git diff --stat,列出有變更的文件,不顯示變更的具體內容
也可以比較兩個分支(后者與前者相比)
補充,git diff結果的含義
diff --git a/text.txt b/text.txt,表示文件text.txt的兩個版本
--- a/text.txt,---表示更改前的文件
+++ b/text.txt,+++表示更改后的文件
@@ -2,3 +2,4 @@ hello test,文件差異的區域,-2,3表示變更前從第2行開始,到第3行,+2,4表示變更后從第2行開始,到第四行
第一次修改
第二次修改
test分支:第一次修改
+test分支:第二次修改,+表示新增了一行,-表示刪除了一行,如果對一行內容進行修改,在此處體現出來的就是先刪除一行,再新增一行
分支合並&沖突解決
git merge 分支名,表示用指定分支和當前分支進行合並
克隆空項目,從頭開始
再創建一個文件並提交
創建並切換到分支test
修改文件
提交
切換到master分支,test2.txt內容沒有變
合並分支,然后可以看到test分支修改的內容
切換到test分支
修改文件
提交
切到master分支
修改同一個文件
提交
合並test,產生沖突
文件內容
最終改為test分支上的
提交
查看沖突的文件:git diff --name-only --diff-filter=U
回退並查看沖突文件
其它相關
git在windows及linux(源碼編譯)環境下安裝:https://www.cnblogs.com/uncleyong/p/10767747.html
git常用命令(測試必備):https://www.cnblogs.com/uncleyong/p/10854115.html
git常用命令速查表:https://www.cnblogs.com/uncleyong/p/11926737.html
如何獲取gitee上的項目?:https://www.cnblogs.com/uncleyong/p/10850182.html
git fetch 和git pull 的差別:https://www.cnblogs.com/uncleyong/p/10655081.html
老鐵,這年頭得玩玩這個:Git基本操作【github】:https://www.cnblogs.com/uncleyong/p/6892171.html
本地Git與GitHub服務器建立連接(SSH方式通信):https://www.cnblogs.com/uncleyong/p/6891958.html
更新本地git倉庫的遠程地址(remote地址):https://www.cnblogs.com/uncleyong/p/7106541.html
ssh-key 與 git賬戶配置以及多賬戶配置,以及通信方式從https切換到ssh:https://www.cnblogs.com/uncleyong/p/9668249.html
本地倉庫推送到遠程倉庫:fatal: refusing to merge unrelated histories:https://www.cnblogs.com/uncleyong/p/10654244.html
在瀏覽器中瀏覽git上項目目錄結構:https://www.cnblogs.com/uncleyong/p/10659295.html
push的時候報錯:Permission denied (publickey):https://www.cnblogs.com/uncleyong/p/10676922.html