git用法總結詳細
參考
https://mp.weixin.qq.com/s/xoyQ4TzVKLQb2VjZJLUqFQ
https://mp.weixin.qq.com/s/acP4yklWYf5TwOrLB41JYg
https://mp.weixin.qq.com/s/rk8e77pYkbsm9NEKA7n_sA
https://mp.weixin.qq.com/s/REbnSmd6CuOeJMUCnqMnWg
https://mp.weixin.qq.com/s/rQmjiV2u6uV__H9RrOS49w
https://www.runoob.com/git/git-tutorial.html
一、Github 基礎
1、什么是 Git?
git 是一個分布式版本控制軟件,最初由林納斯·托瓦茲(Linus Torvalds)(Linux 之父)創作,於 2005 年發布。最初目的是為更好地管理 Linux 內核開發。Git 在本地磁盤上就保存着所有有關當前項目的歷史更新,處理速度快;Git 中的絕大多數操作都只需要訪問本地文件和資源,不用實時聯網。
2、Git 客戶端
TortoiseGit 是一個 Git 版本控制客戶端,作為 Microsoft Windows 的外殼擴展實現,用戶界面友好,大多數人應該用過 TortoiseSvn;
MsysGit 是一個輕量級的 Git 工具集,可以進行各種 Git 操作,MsysGit 又分為簡單的界面 Git GUI,和命令行 Git Bash,我們這節課主要通過 Git Bash 來演示。
3、Git 服務端:GitHub 和 Gitlab
GitHub 是一個共享虛擬主機服務,用於存放使用 Git 版本控制的軟件代碼和內容項目;允許用戶跟蹤其他用戶、組織、軟件庫的動態,對軟件代碼的改動和 bug 提出評論。
GitLab 是一個利用 Ruby on Rails 開發的開源應用程序,實現一個自托管的Git 項目倉庫,可通過 Web 界面進行訪問公開的或者私人項目,擁有與 Github類似的功能,能夠瀏覽源代碼,管理缺陷和注釋。
4、Git 基本概念
4.1、Git的四大工作區域
在Git中有四個概念:「遠程倉庫、工作區、暫存區、版本庫」
- Workspace:你電腦本地看到的文件和目錄,在Git的版本控制下,構成了工作區。
- Index/Stage:暫存區,一般存放在 .git目錄下,即.git/index,它又叫待提交更新區,用於臨時存放你未提交的改動。比如,你執行git add,這些改動就添加到這個區域啦。
- Repository:本地倉庫,你執行git clone 地址,就是把遠程倉庫克隆到本地倉庫。它是一個存放在本地的版本庫,其中HEAD指向最新放入倉庫的版本。當你執行git commit,文件改動就到本地倉庫來了~
- Remote:遠程倉庫,就是類似github,碼雲等網站所提供的倉庫,可以理解為遠程數據交換的倉庫~
四個區域實現的原理圖
這四個區域實現的原理圖所下所示,使用過Git的對於下面的命令再熟悉不過了。
初始化的時候Git還會自動為我們創建第一個分支master
,以及指向master的一個指針叫做HEAD
git 的正向工作流程一般就這樣:
- 從遠程倉庫拉取文件代碼回來;
- 在工作目錄,增刪改查文件;
- 把改動的文件放入暫存區;
- 將暫存區的文件提交本地倉庫;
- 將本地倉庫的文件推送到遠程倉庫;
4.2、Git文件的四種狀態
Git文件的四種狀態
根據一個文件是否已加入版本控制,可以把文件狀態分為:Tracked(已跟蹤)和Untracked(未跟蹤),而tracked(已跟蹤)又包括三種工作狀態:Unmodified,Modified,Staged
- Untracked: 文件還沒有加入到git庫,還沒參與版本控制,即未跟蹤狀態。這時候的文件,通過git add 狀態,可以變為Staged狀態
- Unmodified:文件已經加入git庫, 但是呢,還沒修改, 就是說版本庫中的文件快照內容與文件夾中還完全一致。Unmodified的文件如果被修改, 就會變為Modified. 如果使用git remove移出版本庫, 則成為Untracked文件。
- Modified:文件被修改了,就進入modified狀態啦,文件這個狀態通過stage命令可以進入staged狀態
- staged:暫存狀態. 執行git commit則將修改同步到庫中, 這時庫中的文件和本地文件又變為一致, 文件為Unmodified狀態.
二、Git之命令
1、git init 初始化
用法:git init [repository name]
$ mkdir runoob
$ cd runoob/ $ git init Initialized empty Git repository in /Users/tianqixin/www/runoob/.git/
2、配置用戶名和郵件git config
用法:git config –global user.name “[name]”
用法:git config –global user.email “[email address]”
該命令將分別設置提交代碼的用戶名和電子郵件地址。
git config --global user.name "your name"
git config --global user.email "your email"
3、git clone用法
git clone <repo> <directory>
參數說明:
- repo:Git 倉庫。
- directory:本地目錄。
比如,要克隆 Ruby 語言的 Git 代碼倉庫 Grit,可以用下面的命令:
git clone git://github.com/schacon/grit.git
執行該命令后,會在當前目錄下創建一個名為grit的目錄,其中包含一個 .git 的目錄,用於保存下載下來的所有版本記錄。
如果要自己定義要新建的項目目錄名稱,可以在上面的命令末尾指定新的名字:
git clone git://github.com/schacon/grit.git mygrit
4、添加到暫存區git add
# 添加一個文件 $ git add test.js # 添加一個子目錄中的文件 $ git add /path/to/file/test.js # 支持正則表達式 $ git add ./*.js # 添加指定文件到暫存區 $ git add [file1] [file2] ... # 添加指定目錄到暫存區,包括子目錄 $ git add [dir] # 添加當前目錄的所有文件到暫存區 $ git add . # 添加每個變化前,都會要求確認 # 對於同一個文件的多處變化,可以實現分次提交 $ git add -p
5、提交到本地倉庫git commit
# 提交暫存區的指定文件到倉庫區
$ git commit [file1] [file2] ... -m [message]
# 提交工作區自上次commit之后的變化,直接到倉庫區(相當於運行git add把所有文件加入暫存區,然后再運行git commit把文件提交本地倉庫。)
$ git commit -a
# 提交時顯示所有diff信息
$ git commit -v
# 使用一次新的commit,替代上一次提交
# 如果代碼沒有任何新變化,則用來改寫上一次commit的提交信息
$ git commit --amend -m [message]
# 重做上一次commit,並包括指定文件的新變化
$ git commit --amend [file1] [file2] ...
git commit -m [message] 提交暫存區到倉庫區,message為說明信息
git commit [file1] -m [message] 提交暫存區的指定文件到本地倉庫
運行git commit -a
相當於運行git add
把所有文件加入暫存區,然后再運行git commit
把文件提交本地倉庫。
6、刪除git rm
rm 和上面的 add 命令相反,從工作空間中去掉某個文件
# 移除 HelloWorld.js $ git rm HelloWorld.js # 移除子目錄中的文件 $ git rm /pather/to/the/file/HelloWorld.js # 刪除工作區文件,並且將這次刪除放入暫存區 $ git rm [file1] [file2] ... # 停止追蹤指定文件,但該文件會保留在工作區 $ git rm --cached [file]
7、查看修改內容(工作區和倉庫的區別)git diff
git diff 顯示暫存區和工作區的差異
git diff filepath filepath路徑文件中,工作區與暫存區的比較差異
git diff HEAD filepath 工作區與HEAD ( 當前工作分支)的比較差異
git diff branchName filepath 當前分支的文件與branchName分支的文件的比較差異
git diff commitId filepath 與某一次提交的比較差異
# 顯示暫存區和工作區的差異
$ git diff
# 顯示暫存區和上一個commit的差異
$ git diff --cached [file]
# 顯示工作區與當前分支最新commit之間的差異
$ git diff HEAD
# 顯示兩次提交之間的差異
$ git diff [first-branch]...[second-branch]
# 顯示今天你寫了多少行代碼
$ git diff --shortstat "@{0 day ago}"
# 比較暫存區和版本庫差異
$ git diff --staged
# 比較暫存區和版本庫差異
$ git diff --cached
# 僅僅比較統計信息
$ git diff --stat
8、git遠程操作
遠程操作
- git remote 遠程倉庫操作
- git fetch 從遠程獲取代碼庫
- git pull 下載遠程代碼並合並
- git push 上傳遠程代碼並合並
8.1、添加遠程服務器git remote
8.1.1、git remote 命用於在遠程倉庫的操作。
本章節內容我們將以 Github 作為遠程倉庫來操作,所以閱讀本章節前需要先閱讀關於 Github 的相關內容:Git 遠程倉庫(Github)。
8.1.2、顯示所有遠程倉庫git remote -v
git remote -v
以下我們先載入遠程倉庫,然后查看信息:
$ git clone https://github.com/tianqixin/runoob-git-test $ cd runoob-git-test $ git remote -v origin https://github.com/tianqixin/runoob-git-test (fetch) origin https://github.com/tianqixin/runoob-git-test (push)
8.1.3、顯示某個遠程倉庫的信息git remote show [remote]
origin 為遠程地址的別名
git remote show [remote]
$ git remote show https://github.com/tianqixin/runoob-git-test * remote https://github.com/tianqixin/runoob-git-test Fetch URL: https://github.com/tianqixin/runoob-git-test Push URL: https://github.com/tianqixin/runoob-git-test HEAD branch: master Local ref configured for 'git push': master pushes to master (local out of date)
8.1.4、添加遠程版本庫git remote add [shortname] [url]
git remote add [shortname] [url]
shortname 為本地的版本庫,例如:
# 提交到 Github $ git remote add origin git@github.com:tianqixin/runoob-git-test.git $ git push -u origin master
8.1.5、其他相關命令
git remote rm name # 刪除遠程倉庫
git remote rename old_name new_name # 修改倉庫名
其他命令
git remote add dcmsStatics4.5git(別名)http://gitlab.cephchina.com/ccod_project/dcmsstatics4-5git.git 添加遠程服務器
git remote -v 查看遠程服務器的相關信息 git remote show dcmsStatic4.5git 查看遠程服務器的相關信息 git remote rename demo test 重命名遠程倉庫信 git remote rm test 刪除遠程倉庫
8.2、從遠端版本庫合並到當前分支git pull
8.2.1、git pull 命令用於從遠程獲取代碼並合並本地的版本。
git pull 其實就是 git fetch 和 git merge FETCH_HEAD 的簡寫。 命令格式如下:
git pull <遠程主機名> <遠程分支名>:<本地分支名>
實例
更新操作:
$ git pull
$ git pull origin
將遠程主機 origin 的 master 分支拉取過來,與本地的 brantest 分支合並。
git pull origin master:brantest
如果遠程分支是與當前分支合並,則冒號后面的部分可以省略。
git pull origin master
上面命令表示,取回 origin/master 分支,再與本地的 brantest 分支合並。
上面的 pull 操作用 fetch 表示為:
以 https://github.com/tianqixin/runoob-git-test 為例,遠程載入合並本地分支。
$ git remote -v # 查看信息 origin https://github.com/tianqixin/runoob-git-test (fetch) origin https://github.com/tianqixin/runoob-git-test (push) $ git pull origin master From https://github.com/tianqixin/runoob-git-test * branch master -> FETCH_HEAD Already up to date.
面命令表示,取回 origin/master 分支,再與本地的 master 分支合並。
其他命令
# 從遠端origin的master分支更新版本庫
# git pull <遠端> <分支> $ git pull origin master # 抓取遠程倉庫所有分支更新並合並到本地,不要快進合並 $ git pull --no-ff
8.3、從將本地的分支版本上傳到遠程並合並git push
8.3.1、git push 命用於從將本地的分支版本上傳到遠程並合並。
命令格式如下:
git push <遠程主機名> <本地分支名>:<遠程分支名>
如果本地分支名與遠程分支名相同,則可以省略冒號:
git push <遠程主機名> <本地分支名>
實例
以下命令將本地的 master 分支推送到 origin 主機的 master 分支。
git push origin master
相等於:
git push origin master:master
如果本地版本與遠程版本有差異,但又要強制推送可以使用 --force 參數:
git push --force origin master
刪除主機但分支可以使用 --delete 參數,以下命令表示刪除 origin 主機的 master 分支:
git push origin --delete master
以 https://github.com/tianqixin/runoob-git-test 為例,本地添加文件:
$ touch runoob-test.txt # 添加文件 $ git add runoob-test.txt $ git commit -m "添加到遠程" master 69e702d] 添加到遠程 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 runoob-test.txt $ git push origin master # 推送到 Github
將本地的 master 分支推送到 origin 主機的 master 分支。
8.4、命令用於從遠程獲取代碼庫git fetch
git fetch 命令用於從遠程獲取代碼庫。
本章節內容我們將以 Github 作為遠程倉庫來操作,所以閱讀本章節前需要先閱讀關於 Github 的相關內容:Git 遠程倉庫(Github)。
該命令執行完后需要執行 git merge 遠程分支到你所在的分支。
從遠端倉庫提取數據並嘗試合並到當前分支:
git merge
該命令就是在執行 git fetch 之后緊接着執行 git merge 遠程分支到你所在的任意分支。
假設你配置好了一個遠程倉庫,並且你想要提取更新的數據,你可以首先執行:
git fetch [alias]
以上命令告訴 Git 去獲取它有你沒有的數據,然后你可以執行:
git merge [alias]/[branch]
以上命令將服務器上的任何更新(假設有人這時候推送到服務器了)合並到你的當前分支。
以 https://github.com/tianqixin/runoob-git-test 為例。
接下來我們在 Github 上點擊 README.md 並在線修改它:
然后我們在本地更新修改。
$ git fetch origin remote: Counting objects: 3, done. remote: Compressing objects: 100% (2/2), done. remote: Total 3 (delta 0), reused 0 (delta 0), pack-reused 0 Unpacking objects: 100% (3/3), done. From github.com:tianqixin/runoob-git-test 0205aab..febd8ed master -> origin/master
以上信息"0205aab..febd8ed master -> origin/master" 說明 master 分支已被更新,我們可以使用以下命令將更新同步到本地:
$ git merge origin/master Updating 0205aab..febd8ed Fast-forward README.md | 1 + 1 file changed, 1 insertion(+)
查看 README.md 文件內容:
$ cat README.md
# 菜鳥教程 Git 測試
## 第一次修改內容
9、撤銷與回退
9.1、有關於Git的撤銷與回退,一般就以下幾個核心命令
- git checkout
- git reset
- git revert
Git的撤銷與回退,在日常工作中使用的比較頻繁。比如我們想將某個修改后的文件撤銷到上一個版本,或者想撤銷某次多余的提交,都要用到git的撤銷和回退操作。
代碼在Git的每個工作區域都是用哪些命令撤銷或者回退的呢,如下圖所示:
9.2、git checkout
9.2.1、如果文件還在工作區,還沒添加到暫存區,可以使用git checkout撤銷
git checkout [file] 丟棄某個文件file
git checkout . 丟棄所有文件
以下demo,使用git checkout -- test.txt 撤銷了test.txt的修改
9.3、git reset
9.3.1、git reset的理解
git reset的作用是修改HEAD的位置,即將HEAD指向的位置改變為之前存在的某個版本.
為了更好地理解git reset,我們來回顧一下,Git的版本管理及HEAD的理解
Git的所有提交,會連成一條時間軸線,這就是分支。如果當前分支是master,HEAD指針一般指向當前分支,如下:
假設執行git reset,回退到版本二之后,版本三不見了哦,如下:
9.4、git reset的使用
9.4.1、Git Reset的幾種使用模式
git reset HEAD --file 回退暫存區里的某個文件,回退到當前版本工作區狀態 git reset –-soft 目標版本號 可以把版本庫上的提交回退到暫存區,修改記錄保留 git reset –-mixed 目標版本號 可以把版本庫上的提交回退到工作區,修改記錄保留 git reset –-hard 可以把版本庫上的提交徹底回退,修改的記錄全部revert。
9.4.2、代碼git add到暫存區,並未commit提交,可以醬紫回退,如下:
git reset HEAD file 取消暫存
git checkout file 撤銷修改
9.4.3、再看另外一個粟子吧,代碼已經git commit了,但是還沒有push:
git log 獲取到想要回退的commit_id
git reset --hard commit_id 想回到過去,回到過去的commit_id
9.4.4、如果代碼已經push到遠程倉庫了,也可以使用reset回滾
git log git reset --hard commit_id git push origin HEAD --force
9.5、git revert
與git reset不同的是,revert復制了那個想要回退到的歷史版本,將它加在當前分支的最前端。
revert之前:
revert 之后:
當然,如果代碼已經推送到遠程的話,還可以考慮revert回滾
git log 得到你需要回退一次提交的commit id
git revert -n <commit_id> 撤銷指定的版本,撤銷也會作為一次提交進行保存
10、標簽tag
10.1、創建
標簽分類
輕量級標簽:
git tag <tagname> commit id
帶說明標簽:
git tag -a <tagname> commit id
git tag -m <msg> <tagname> commit id
10.2、查看和刪除
查看標簽:
git tag
git tag –n
git show <tagname>
刪除標簽:
git tag -d <tagname>
10.3、共享標簽
向上游版本庫提交標簽:
git push origin <tagname>
git push origin --tags
刪除遠程版本庫的標簽:
git push origin :tag2
10.4、其他資料
# 顯示commit歷史,以及每次commit發生變更的文件 $ git log --stat # 搜索提交歷史,根據關鍵詞 $ git log -S [keyword] # 顯示某個commit之后的所有變動,每個commit占據一行 $ git log [tag] HEAD --pretty=format:%s # 顯示某個commit之后的所有變動,其"提交說明"必須符合搜索條件 $ git log [tag] HEAD --grep feature # 顯示某個文件的版本歷史,包括文件改名 $ git log --follow [file] $ git whatchanged [file] # 顯示指定文件相關的每一次diff $ git log -p [file] # 顯示過去5次提交 $ git log -5 --pretty --oneline
10.5、打tag
打tag就是對發布的版本標注一個版本號,如果版本發布有問題,就把該版本拉取出來,修復bug,再合回去。
git tag 列出所有tag git tag [tag] 新建一個tag在當前commit git tag [tag] [commit] 新建一個tag在指定commit git tag -d [tag] 刪除本地tag git push origin [tag] 推送tag到遠程 git show [tag] 查看tag git checkout -b [branch] [tag] 新建一個分支,指向某個tag
11、git stash
stash命令可用於臨時保存和恢復修改
git stash 把當前的工作隱藏起來 等以后恢復現場后繼續工作
git stash list 顯示保存的工作進度列表
git stash pop stash@{num} 恢復工作進度到工作區
git stash show :顯示做了哪些改動
git stash drop stash@{num} :刪除一條保存的工作進度
git stash clear 刪除所有緩存的stash。
12、git reflog
顯示當前分支的最近幾次提交
13、git blame filepath
git blame 記錄了某個文件的更改歷史和更改人,可以查看背鍋人
三、git分支
# 顯示當前分支的最近幾次提交 $ git reflog # 查看遠程分支 $ git br -r # 創建新的分支 $ git br <new_branch> # 查看各個分支最后提交信息 $ git br -v # 查看已經被合並到當前分支的分支 $ git br --merged # 查看尚未被合並到當前分支的分支 $ git br --no-merged # 查看所有的分支和遠程分支 $ git branch -a # 創建一個新的分支 $ git branch [branch-name] # 重命名分支 # git branch -m <舊名稱> <新名稱> $ git branch -m [branch-name] [new-branch-name] # 編輯分支的介紹 $ git branch [branch-name] --edit-description # 列出所有本地分支 $ git branch # 列出所有遠程分支 $ git branch -r # 新建一個分支,但依然停留在當前分支 $ git branch [branch-name] # 新建一個分支,並切換到該分支 $ git checkout -b [branch] # 新建一個分支,指向指定commit $ git branch [branch] [commit] # 新建一個分支,與指定的遠程分支建立追蹤關系 $ git branch --track [branch] [remote-branch] # 切換到指定分支,並更新工作區 $ git checkout [branch-name] # 切換到上一個分支 $ git checkout - # 建立追蹤關系,在現有分支與指定的遠程分支之間 $ git branch --set-upstream [branch] [remote-branch] # 合並指定分支到當前分支 $ git merge [branch] # 選擇一個commit,合並進當前分支 $ git cherry-pick [commit] # 刪除分支 $ git branch -d [branch-name] # 刪除遠程分支 $ git push origin --delete [branch-name] $ git branch -dr [remote/branch] # 切換到某個分支 $ git co <branch> # 創建新的分支,並且切換過去 $ git co -b <new_branch> # 基於branch創建新的new_branch $ git co -b <new_branch> <branch> # 把某次歷史提交記錄checkout出來,但無分支信息,切換到其他分支會自動刪除 $ git co $id # 把某次歷史提交記錄checkout出來,創建成一個分支 $ git co $id -b <new_branch> # 刪除某個分支 $ git br -d <branch> # 強制刪除某個分支 (未被合並的分支被刪除的時候需要強制) $ git br -D <branch> # 下載遠程倉庫的所有變動 $ git fetch [remote] # 顯示所有遠程倉庫 $ git remote -v # 顯示某個遠程倉庫的信息 $ git remote show [remote] # 增加一個新的遠程倉庫,並命名 $ git remote add [shortname] [url] # 查看遠程服務器地址和倉庫名稱 $ git remote -v # 添加遠程倉庫地址 $ git remote add origin git@ github:xxx/xxx.git # 設置遠程倉庫地址(用於修改遠程倉庫地址) $ git remote set-url origin git@ github.com:xxx/xxx.git # 刪除遠程倉庫 $ git remote rm <repository> # 上傳本地指定分支到遠程倉庫 # 把本地的分支更新到遠端origin的master分支上 # git push <遠端> <分支> # git push 相當於 git push origin master $ git push [remote] [branch] # 強行推送當前分支到遠程倉庫,即使有沖突 $ git push [remote] --force # 推送所有分支到遠程倉庫 $ git push [remote] --all
四、git沖突