Git基礎常用功能
一、安裝
具體檢視 安裝Git
二、使用
基礎知識
- 工作區(Workspace):就是你在電腦裡能看到的專案目錄。
- 暫存區(Index / Stage):臨時存放更改的地方,使用命令"git add <.|file>"就是把檔案加入暫存區。一般存放在 ".git目錄下" 下的index檔案(.git/index)中,所以我們把暫存區有時也叫作索引(index)。
- 版本庫(Repository):管理版本的檔案,使用"git commit -m 'description'"就是把暫存區的檔案提交到版本庫。工作區有一個隱藏目錄.git,這個不算工作區,而是Git的版本庫。
- 遠端倉庫(Remote):託管程式碼的伺服器。可以簡單的認為是你專案組中的一臺電腦用於遠端資料交換
一張圖描述git的檔案如何在各個區域之前流轉:
origin:遠端倉庫庫預設別名
master: 倉庫預設分支的名稱本地專案初始化/和遠端倉庫操作
git init,把當前資料夾初始化位git工程 git remote add [<options>] <name> <url> 把當前資料夾關聯遠端倉庫並命名,比如git remote add origin git@server-name:path/repo-name.git; git remote -v 檢視遠端倉庫地址 git push <遠端主機名> <本地分支名> <遠端分支名>,比如 git push origin dev dev git push -u origin master 如果當前分支與多個主機存在追蹤關係,則可以使用 -u 引數指定一個預設主機,這樣後面就可以不加任何引數使用git push基本操作:新增/提交/檢視記錄
git cherry-pick <commitId>,複製一個特定的提交到當前分支,比如master分支的bug修復提交複製到dev分支
倉庫分支管理
檢視分支:git branch 建立分支:git branch <name> 切換分支:git checkout <name>或者git switch <name> 建立+切換分支:git checkout -b <name>或者git switch -c <name> 比如git checkout -b dev,切換並建立dev分支,相當於 $ git branch dev $ git checkout dev 合併某分支到當前分支:git merge <name> 正常合併如果能用fast-forward就會使用, 但這種模式下,刪除分支後,會丟掉分支資訊。可以使用--no-ff強制禁用ff模式 git merge --no-ff -m "merge with no-ff" dev 因為本次合併要建立一個新的commit,所以加上-m引數,把commit描述寫進去。 刪除分支:git branch -d <name>程式碼回退
看上面的幾個區域的圖基本就能明白
"git reset HEAD" 或者"git reset HEAD <file>"命令,暫存區的目錄樹或檔案會被重寫,被 master 分支指向的目錄樹或檔案所替換,但是工作區不受影響。
git reset --hard HEAD^/git reset --hard 1094a,強制回退上一個版本/回退到指定版本號的版本,版本庫會直接回退(遠端倉庫不會回退),需要特別謹慎。版本號沒必要寫全,前幾位就可以了,Git會自動去找。當然也不能只寫前一兩位,因為Git可能會找到多個版本號,就無法確定是哪一個了"git rm --cached <file>" 命令,會直接從暫存區刪除檔案,工作區則不做出改變。
"git checkout ." 或者 "git checkout -- <file>" 命令,會用暫存區全部或指定的檔案替換工作區的檔案。這個操作很危險,會清除工作區中未新增到暫存區的改動。
"git checkout HEAD ." 或者 "git checkout HEAD <file>" 命令時,會用 HEAD 指向的 master 分支中的全部或者部分檔案替換暫存區和以及工作區中的檔案。這個命令也是極具危險性的,因為不但會清除工作區中未提交的改動,也會清除暫存區中未提交的改動。
“git revert HEAD/git revert commitID”: 放棄已經push的指定版本的修改,會新增一條記錄,版本會遞增 "git reflog" , 用來檢視你的每一條命令,用來配合上面的命令恢復你的誤操作 例1:將單個檔案(a.js)回退到某一版本- git log a.js檢視a.js的更改記錄
- git reset fcd2093 a.js 先將暫存區中的該檔案回退到歷史版本fcd2093
- git checkout -- a.js 暫存區中該檔案的歷史版本(fcd2093)覆蓋工作區中對應的檔案,此時(工作區、暫存區的檔案a.js是fcd2093版本)。
- git reset --hard aaaa 強制將版本庫回退到aaaa,但是遠端倉庫還是cccc
- git reset cccc 將head移到最新的版本(和遠端的head保持一致,實際就是將遠端暫存區的內容更新到最新版本cccc,工作區的內容還是保持在aaaa),此時aaaa和cccc的差異便作為本次更改的內容。
- git add / git commit / git push 提交後生成新的版本號dddd
此時git log 看到的最近的提交記錄就是:aaaa -> bbbb -> cccc -> dddd
【注】也可以使用git revert cccc 和 git revert bbbb來實現,不過會新增兩條回滾記錄
保留半成品現場(儲存臨時現場)
主要用在目前還不想提交的但是已經修改的內容進行儲存至堆疊中,後續可以在某個分支上恢復出堆疊中的內容 git stash 儲存臨時現場 git stash list 檢視工作臨時現場 一是用git stash apply恢復,但是恢復後,stash內容並不刪除,你需要用git stash drop來刪除; 另一種方式是用git stash pop,恢復的同時把stash內容也刪了 你可以多次stash,恢復的時候,先用git stash list檢視,然後恢復指定的stash,用命令: git stash apply stash@{0}子模組
有時工程太過龐大想要分出子工程單獨管理,或者納入一個子工程到當前工程來,就可能用到子模組功能。
git子模組配置處理(即git的B倉庫被作為A倉庫的子目錄),兩個倉庫可以各自管理和提交 git submodule add <path> <name>:將<path>對應的倉庫作為當前倉庫A的<name>子目錄 git status:在A中檢視發現多了<name>和 .gitmodules(這個檔案中是子模組的相關配置) git diff --cached <name>:在A中看到無法查詢子模組的提交記錄, 取而代之的是,Git 將它記錄成來自B倉庫的一個特殊的提交(這個提交在克隆的該專案時,進入子模組就是進入到這個提交) 例如,子模組B的名稱為subproject_demo:$ git diff --cached subproject_demo diff --git a/subproject_demo b/subproject_demo new file mode 160000 index 0000000..aa1eeb0 --- /dev/null +++ b/subproject_demo @@ -0,0 +1 @@ +Subproject commit aa1eeb06e67608d7a2af179a7dfd9e594777e90fgit commit -m 'first commit with submodule xxx': 結果中注意 subproject_demo條目的 160000 模式。這在Git中是一個特殊模式,基本意思是你將一個提交記錄為一個目錄項而不是子目錄或者檔案。 當你使用clone克隆該專案(父工程A)時,會發現子模組的資料夾內容為空,需要做: git submodule init: 初始化你的本地配置檔案 git submodule update:從子模組B拉取所有資料並檢出你上層專案裡所列的合適的提交(保持子模組是最新的那個) 進入子模組,發現子模組是那個專案的 你先前提交的確切狀態的分支
chen_@DESKTOP-TJKEMKG MINGW64 /c/works/demo/subproject_demo ((aa1eeb0...)) // 發現沒:aa1eeb0就是之前的哪個提交
如果你在專案中改了子模組的程式碼,準備提交到對應的分支(add和commit已經執行過),使用:
git push origin HEAD:<branch> 這樣就把程式碼提交到對應的分支 ,和 git push origin <localBranch> <remoteBranch>類似
如果其他人有修改這個子模組並提交到A工程,你可以重新pull A專案分支,然後執行git submodule update保證子模組也是最新的 git clone --recurse-submodules <repositary> ,他就會自動初始化並更新倉庫的每一個子模組 【注】使用時要注意,最好保證在父工程A中來自B的提交永遠來自同一個B的分支,比如master分支。所以B的分支程式碼更改完畢並測試完畢合併到master後,再在A提交來自B的master分支的提交【注】引入私有git工程還可以又其他方式,比如和npm配合:《2018 年了,你還是隻會 npm install 嗎》檢視“私有 git 共享 package”部分
https和ssh使用
檢視連結:https://blog.csdn.net/qq_42108192/article/details/90168968
https模式下新增git賬號到專案,push不用每次輸入賬號密碼
開啟.git檔案的下的 vim .git/config新增以下內容
[user] name = [email protected] email = [email protected] [credential] helper=store
三、踩坑
[remote rejected] (hook declined)
完整日誌:
$ git push Enumerating objects: 25, done. Counting objects: 100% (24/24), done. Delta compression using up to 8 threads Compressing objects: 100% (13/13), done. Writing objects: 100% (13/13), 1.20 KiB | 1.20 MiB/s, done. Total 13 (delta 11), reused 0 (delta 0) remote: git: 'refs/heads/web2.0' is not a git command. See 'git --help'. remote: error: hook declined to update refs/heads/web2.0 To https://e.coding.net/tops/front-www.git ! [remote rejected] web2.0 -> web2.0 (hook declined) error: failed to push some refs to 'https://e.coding.net/tops/front-www.git'
百度檢視幫助,找到類似的問題:https://blog.csdn.net/weixin_39278265/article/details/102248258
本人的問題解決辦法
git config --global --unset branch.web2.0.merge
然後再push