git從安裝到應用的學習
本文內容是對廖雪峰老師Git教程做的筆記,外加一些自己的學習心得,還抱著學以致用的心態來實踐一番
Git學習筆記
分布式版本控制與集中式版本控制的最大區別
集中式的版本控制,本地沒有歷史記錄,完整的倉庫只存在服務器上,如果服務器掛了,就全都掛了,而分布式如果github掛了可以重建一個服務器,然後把任何一個人的倉庫clone過去 一句話總結:分布式版本控制的每個節點都是完整倉庫
- Git官網直接下載安裝程序 (網速慢的同學請移步國內鏡像)
- Git User Manual
- Git中文手冊
$ git --help //不知道怎麽辦就看幫助唄
Git簡介
略
安裝Git
下載並安裝Git,安裝完成後,還需要最後一步設置Git Bash
$ git config --global user.name "Your Name"
$ git config --global user.email "[email protected]"
註意git config命令的--global參數,用了這個參數,表示你這臺機器上所有的Git倉庫都會使用這個配置,當然也可以對某個倉庫指定不同的用戶名和Email地址
創建版本庫repository
- 首先建一個空目錄
$ mkdir learngit //當前目錄下創建文件夾名為learngit
$ cd learngit //進入learngit文件夾目錄下
$ pwd //顯示當前目錄
pwd
命令用於顯示當前目錄
- 然後通過
git init
命令把這個目錄變成Git可以管理的倉庫
$ git init //初始化 $ ls -ah //顯示.git目錄
ls -ah
用於顯示.git
目錄
把文件添加到版本庫
編寫一個readme.txt,放在learngit目錄下(或者子目錄)
$ vi readme.txt
Vim | 快捷鍵說明 |
---|---|
Esc | 退出編輯,跳到命令模式 |
:w | 保存文件但不退出vi |
:w file | 將修改另外保存到file中,不退出vi |
:w! | 強制保存,不退出vi |
:wq | 保存文件並退出vi |
:q | 不保存文件,退出vi |
:q! | 不保存文件,強制退出vi |
:e! | 放棄所有修改,從上次保存文件開始再編輯 |
1.把文件添加到暫存區
使用git add file_name
或 git stage file_name
$ git add readme.txt
2.把文件提交到版本庫
$ git commit -m "wrote a readme file"
-m後面是本次提交的說明,一次可以提交多個文件
註意:git commit
指定文件的時候會直接提交工作區的文件,不指定文件的時候提交的是緩存區stage
的所有文件
$ git commit readme.txt -m "balabala"
Git bash操作文件及文件夾命令
命令示例 | 用途 |
---|---|
cd d:\Github | 切換d盤下面的Github目錄 |
cd .. | 回退到上一個目錄 |
cd | 回退到主目錄 |
pwd | 顯示當前目錄路徑 |
ls(ll) | 列出當前目錄中的所有文件,ll更詳細 |
ls(ll) -a | 列出當前目錄中的所有文件包括隱藏目錄 |
touch readme.md | 新建一個文件 |
rm readme.md | 刪除一個文件 |
mkdir img | 新建一個文件夾img |
rm -r img | 刪除一個文件夾img |
mv readme.md img | 把當前目錄下的目標文件移動到一個指定目錄,使用相對路徑 |
reset | 清屏,清空git bash 命令窗口中的所有內容 |
查看Git安裝目錄
- Windows
- cmd
where git
- cmd
- Mac
- 命令行
which git
- 命令行
時光穿梭機
版本退回
git reset --hard commit_id
HEAD
指向的版本就是當前版本,因此,Git允許我們在版本的歷史之間穿梭,使用命令git reset --hard commit_id
- Git的
commit_d
(版本號)是一個十六進制的用SHA1計算出來的數字 - 在Git中用
HEAD
表示當前版本,上一個版本就是HEAD^
,上一百個版本寫成HEAD~100
- 使用
git reset --hard HEAD^
命令退回上一個版本
- Git的
- 穿梭前,用
git log
可以查看提交歷史,以便確定要回退到哪個版本- 使用
git log --pretty=oneline
讓記錄單行顯示 - 使用
git log
或git reflog
加file_name
查看指定文件的歷史
- 使用
- 要重返未來,用
git reflog
查看命令歷史,以便確定要回到未來的哪個版本- Git 提供一個命令
git reflog
來記錄你的每一次命令,這樣就可以找到所有版本的commit id
- Git 提供一個命令
工作區和暫存區
- 工作區(Working Directory)
你在電腦裏能看到的目錄 - 版本庫(Repository)
工作區有一個隱藏目錄.git
,這個不算工作區,而是Git的版本庫.我們可以稱它為Repo
Repo裏存放了很多東西,其中最重要的就是暫存區stage
(或者叫index),還有Git為我們自動創建的第一個分支(Branch
)master
.以及指向master
的一個指針叫HEAD
.cat file_name
命令,其功能是顯示在工作區、暫存區和分支裏同名文檔的最新修改版本的內容
前面講了我們把文件往Git版本庫裏添加的時候,是分兩步執行的:
第一步是用git add
把文件添加進去,實際上就是把文件修改添加到暫存區;
第二步是用git commit
提交更改,實際上就是把暫存區的所有內容提交到當前分支。
掌握倉庫當前的狀態
$ git status
查看修改內容
下面是關於 git diff
的一些使用區別
另外可以使用git diff commit_id_1 commit_id_2
比較兩個不同版本的區別
cat file_name
命令,其功能是顯示在工作區、暫存區和分支裏同名文檔的最新修改版本的內容
撤銷修改
- 場景1:當你改亂了工作區某個文件的內容,想直接丟棄工作區的修改時,用命令
git checkout -- file_name
- 可以用
git checkout -- *
丟棄所有工作區文件的修改
- 可以用
- 場景2:當你不但改亂了工作區某個文件的內容,還添加到了暫存區時,想丟棄修改,分兩步
- 第一步用命令
git reset HEAD file_name
就回到了場景1- 使用
git reset HEAD
丟棄所有暫存區的修改
- 使用
- 第二步按場景1操作
- 第一步用命令
- 場景3:已經提交了不合適的修改到版本庫時,想要撤銷本次提交,參考版本回退一節,不過前提是沒有推送到遠程庫。
註意:使用版本退回操作git reset --hard
會導致所有暫存區和工作區的當前修改但未commit的內容全部丟棄. 特別:使用git reset --hard HEAD
會導致上述結果,並在git reflog
中生成記錄,但不改變
文件名裏有空格和()的情況
Git命令(或者所有的shell命令中)中出現括“()”時系統把它看做一個有特殊意義的命令從而嘗試去執行它。
因此如果文件名中出現括號,系統找不到括號裏要執行的命令就會報錯。
我們要讓系統忽略括號的特殊意義,方法是用“”雙引號把文件名括起來,或者用轉義符將括號轉義.
例如文件名為git (1).md
以下的寫法都是可以的:git add "git (1).md"
git add git" "\(1\).md
git add git" (1)".md
刪除文件
使用rm file_name
刪除本地文件
使用 git rm file_name
提交刪除到暫存區
使用git commit -m "balabala"
提交到本地庫
註意: 可以直接使用git rm file_name
刪除本地文件以及提交刪除到暫存區,但僅用於暫存區有此本地文件的情況
遠程倉庫
註冊GitHub賬號
由於你的本地Git倉庫和GitHub倉庫之間的傳輸是通過SSH加密的,所以,需要一點設置:
- 第1步:創建SSH Key
$ ssh-keygen -t rsa -C "[email protected]"
然後在用戶主目錄裏找到.ssh
目錄,裏面有id_rsa
和id_rsa.pub
兩個文件id_rsa
是私鑰,id_rsa.pub
是公鑰.
cd ~
進入用戶主目錄cd .ssh
進入.ssh目錄ls
列出.ssh目錄的文件cat ~/.ssh/id_rsa.pub
看到id_rsa.pub文件的內容
- 第2步:登陸GitHub
打開“Account settings”,“SSH Keys”頁面:然後,點“Add SSH Key”,填上任意Title,在Key文本框裏粘貼id_rsa.pub文件的內容
添加遠程庫
- 要關聯一個遠程庫,使用命令
git remote add origin git@server_name:path/repo_name.git
這裏使用的命令是 git remote add origin [email protected]:HuChanghong/learngit.git
-
關聯後,使用命令
git push -u origin master
第一次推送master分支的所有內容 -
此後,每次本地提交後,只要有必要,就可以使用命令
git push origin master
推送最新修改
ssh不行是因為你沒有設置ssh秘鑰
1:生成秘鑰:ssh-keygen -t rsa -C "你自己的郵箱"
(這裏不要設置密碼,直接按回車就可以,以後更新就不需要密碼)
2:id_rsa
這個文件是你的私鑰、id_rsa.pub
是你的公共密鑰,用記事本打開文件id_rsa.pub
,把裏面的內容復制到github配置ssh
3:添加私秘鑰到ssh:ssh-add id_rsa
(如果添加失敗可以先執行命令ssh-agent bash
,然後再次添加私秘鑰。)
4: 用ssh -T [email protected]
判斷是否綁定成功。如果返回successfully 表示成功
從遠程庫克隆
- 要克隆一個倉庫,首先必須知道倉庫的地址,然後使用
git clone
命令克隆。
git clone [email protected]:HuChanghong/MarkdownStudy.git
- Git支持多種協議,包括
https
,但通過ssh
支持的原生git
協議速度最快。
取消鏈接並刪除本地庫
- 查看本地庫關聯了那些遠程庫
git remote -v
- 取消本地目錄下關聯的遠程庫
git remote rm origin
- 此處
origin
是指你創建與遠程庫的鏈接的時候所使用的名字
- 此處
- 刪除本地庫
git branch
#顯示本地所有分支git init
1#初始化倉庫ls -a
2#查看內部文件rm -rf .git
3#強刪.gitcd ..
5#回退rm -rf file_name
6# 強刪文件夾
分支管理
創建與合並分支
- 查看分支:
git branch
- 創建分支:
git branch <name>
- 切換分支:
git checkout <name>
- 創建+切換分支:
git checkout -b <name>
- 合並某分支到當前分支:
git merge <name>
- 刪除分支:
git branch -d <name>
解決沖突
- 當Git無法自動合並分支時,就必須首先解決沖突。
- 解決沖突後,再提交,合並完成。
- 解決沖突就是把Git合並失敗的文件手動編輯為我們希望的內容,再提交。
- 用git log --graph命令可以看到分支合並圖。
git merge branch_name
提示conflict
git status
查看沖突的文件
打開這個文件,修改保存
用帶參數的git log也可以看到分支的合並情況:git log --graph --pretty=oneline --abbrev-commit
最後刪除不需要的分支
分支管理策略
在實際開發中,我們應該按照幾個基本原則進行分支管理:首先,
master
分支應該是非常穩定的,也就是僅用來發布新版本,平時不能在上面幹活;那在哪幹活呢?幹活都在dev
分支上,也就是說,dev
分支是不穩定的,到某個時候,比如1.0版本發布時,再把dev
分支合並到master
上,在master
分支發布1.0版本;你和你的小夥伴們每個人都在dev
分支上幹活,每個人都有自己的分支,時不時地往dev
分支上合並就可以了。
合並分支時,加上--no-ff
參數就可以用普通模式合並,合並後的歷史有分支,能看出來曾經做過合並,而fast forward
合並就看不出來曾經做過合並。
註意--no-ff
參數,表示禁用Fast forward
因為本次合並要創建一個新的commit,所以加上-m
參數,把commit描述寫進去
git merge --no-ff -m "balabala" branch_name
Bug分支
修復bug時,我們會通過創建新的bug分支進行修復,然後合並,最後刪除; 當手頭工作沒有完成時,先把工作現場
git stash
一下,然後去修復bug,修復後,再git stash pop
,回到工作現場。
Git提供了一個stash
功能,可以把當前工作現場“儲藏”起來,等以後恢復現場後繼續工作
git stash
我理解的stash
,就像是把當前的WIP
壓棧(這裏WIP
的含義就是所有修改了但未commit的數據)然後再一個一個取出來,默認的git stash pop
是按照自棧頂開始的順序依次出棧,也可以使用git stash pop stash@{num}
的方式取出指定的WIP
我們可以用git stash list
查看當前壓棧了多少個WIP
註意:git stash
不能將未被追蹤的文件(untracked file)壓棧,也就是從未被git add
過的文件,也就是你在使用git status
命令看到的提示Untracked files
所列出的文件,所以在git stash
之前一定要用git status
確認沒有Untracked files
另外在有WIP
沒有commit
或者stash
的情況下是無法切換分支的
Feature分支
- 開發一個新feature,最好新建一個分支;
- 如果要丟棄一個沒有被合並過的分支,可以通過
git branch -D <name>
強行刪除
多人協作
多人協作的工作模式通常是這樣:
- 首先,可以試圖用
git push origin <branch-name>
推送自己的修改;- 如果推送失敗,則因為遠程分支比你的本地更新,需要先用
git pull
試圖合並;- 如果合並有沖突,則解決沖突,並在本地提交;
- 沒有沖突或者解決掉沖突後,再用
git push origin <branch-name>
推送就能成功!- 如果
git pull
提示no tracking information
,則說明本地分支和遠程分支的鏈接關系沒有創建,用命令git branch --set-upstream-to=origin/<branch-name> <branch-name>
。- 這就是多人協作的工作模式,一旦熟悉了,就非常簡單。
- 查看遠程庫信息,使用
git remote -v
; - 本地新建的分支如果不推送到遠程,對其他人就是不可見的;
- 從本地推送分支,使用
git push origin branch-name
,如果推送失敗,先用git pull
抓取遠程的新提交; - 在本地創建和遠程分支對應的分支,使用
git checkout -b branch-name origin/branch-name
,本地和遠程分支的名稱最好一致; - 建立本地分支和遠程分支的關聯,使用
git branch --set-upstream-to=origin/branch-name branch-name
; - 從遠程抓取分支,使用
git pull
,如果有沖突,要先處理沖突。
rebase
這是git文檔強調的使用註意情形和原則
只對尚未推送或分享給別人的本地修改執行
rebase
操作清理歷史; 從不對已推送至別處的提交執行rebase
操作
gitbook.liuhui998下圖來自這篇鏈接
git rebase
會把你的my work
分支裏的每個提交commit
取消掉,並且把它們臨時 保存為補丁patch
(這些補丁放到".git/rebase"目錄中),然後把mywork
分支更新 到最新的origin
分支,最後把保存的這些補丁應用到mywork
分支上。
當
mywork
分支更新之後,它會指向這些新創建的提交commit
,而那些老的提交會被丟棄。 如果運行垃圾收集命令pruning garbage collection
, 這些被丟棄的提交就會刪除.
標簽管理
發布一個版本時,我們通常先在版本庫中打一個標簽(tag),這樣,就唯一確定了打標簽時刻的版本。將來無論什麽時候,取某個標簽的版本,就是把那個打標簽的時刻的歷史版本取出來。所以,標簽也是版本庫的一個快照。Git的標簽雖然是版本庫的快照,但其實它就是指向某個commit的指針(跟分支很像對不對?但是分支可以移動,標簽不能移動),所以,創建和刪除標簽都是瞬間完成的。
類似IP和域名的關系
創建標簽
- 命令
git tag <tagname>
用於新建一個標簽,默認為HEAD
,也可以指定一個commit id
;git tag tag_name commit_id
- 命令
git tag -a <tagname> -m "blablabla..."
可以指定標簽信息;- 用
-a
指定標簽名,-m
指定說明文字
- 用
- 命令
git tag
可以查看所有標簽。git show tag_name
查看標簽信息
操作標簽
命令git push origin <tagname>
可以推送一個本地標簽; 命令git push origin --tags
可以推送全部未推送過的本地標簽; 命令git tag -d <tagname>
可以刪除一個本地標簽; 命令git push origin :refs/tags/<tagname>
可以刪除一個遠程標簽。
關聯多個遠程庫
使用多個遠程庫時,我們要註意,
git
給遠程庫起的默認名稱是origin
,如果有多個遠程庫,我們需要用不同的名稱來標識不同的遠程庫。
先用git remote -v
查看遠程庫信息
如果本地庫已經關聯了origin
的遠程庫,並且,該遠程庫指向GitHub
。我們可以刪除已有的GitHub
遠程庫
git remote rm origin
使用如下命令關聯遠程庫
git remote add remote_name git@server_name:path/repo_name.git
例如要關聯Github
遠程庫
git remote add github [email protected]:Github_id/repo_name.git
再比如要關聯碼雲
遠程庫
git remote add gitee [email protected]:Github_id/repo_name.git
此時要推送到不同的遠程庫則代碼中使用對應的遠程庫名稱(remote_name
)
git push remote_name master
自定義Git
忽略特殊文件
有些時候,你必須把某些文件放到Git工作目錄中,但又不能提交它們,比如保存了數據庫密碼的配置文件啦,等等,每次
git status
都會顯示Untracked files
...,有強迫癥的童鞋心裏肯定不爽。好在Git考慮到了大家的感受,這個問題解決起來也很簡單,在Git工作區的根目錄下
創建一個特殊的.gitignore
文件,然後把要忽略的文件名填進去,Git就會自動忽略這些文件。不需要從頭寫.gitignore
文件,GitHub已經為我們準備了各種配置文件,只需要組合一下就可以使用了。所有配置文件可以直接在線瀏覽:https://github.com/github/gitignore
忽略文件的原則是:
- 忽略操作系統自動生成的文件,比如縮略圖等;
- 忽略編譯生成的中間文件、可執行文件等,也就是如果一個文件是通過另一個文件自動生成的,那自動生成的文件就沒必要放進版本庫,比如Java編譯產生的.class文件;
- 忽略你自己的帶有敏感信息的配置文件,比如存放口令的配置文件。
可以用git add -f
強制添加被gitignore
的文件 可以用git check-ignore
命令檢查是什麽規則導致的無法添加文件
git check-ignore -v file_name
註意:.gitignore
文件本身要放到版本庫裏,並且可以對.gitignore
做版本管理!
Windows
下創建.gitignore
文件的常用方法
- 在
git bash
中cd
切換到根目錄touch .gitignore
命令創建 - 在資源管理器創建文件時,文件命名“
.gitignore.
”,註意結尾有個.號,回車確認時系統會自動存成.gitignore
- 打開文本編輯器,保存時文件名輸入“
.gitignore
”,保存類型選“所有文件
” - 進入cmd命令行,執行
echo > .gitignore
輸入空內容並創建文件,或執行rename somefile .gitignore
、copy somefile .gitignore
從已有文件復制、重命名。
配置別名
只需要先如此如此
git config --global alias.lg "log --color --graph --pretty=format:‘%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset‘ --abbrev-commit"
然後就可以只用git lg
輸出辣麽一長串的代碼,看到這裏我沈默了,然後我想了半天,我為什麽幹脆不用GitDesktop呢,可能就是因為熱愛敲代碼吧(霧
配置Git的時候,加上--global
是針對當前用戶起作用的,如果不加,那只針對當前的倉庫起作用。 每個倉庫的Git配置文件都放在.git/config
文件,打開配置文件,別名就在[alias]
後面,要刪除別名,直接把對應的行刪掉即可 當前用戶的Git配置文件放在用戶主目錄
下的一個隱藏文件.gitconfig
中
查看用戶的配置信息使用git config --global --list
命令 查看當前倉庫的配置信息使用git config --local --list
命令
刪除別名
命令刪除一個已定義的別名 git config --global --unset alias.ci
cd .git
vi config
打開對應的配置文件,別名就在[alias]
後面,直接把對應的行刪掉即可
gitconfig配置文件的讀取順序: linux中類似用戶的配置文件一樣有3層,系統級,用戶級,項目級。 windows也基本一樣,但常常只存在於是用戶根目錄(C:\User\xxx),項目目錄中。 最下層的覆蓋上面的,alias配置也在其中,手動改配置文件也和命令一樣。 加了--global選項的,表示配置寫到了用戶級,--system是系統級,win是在安裝目錄(如C:\Program Files\Git\mingw64\etc),不加就在項目級
來自:https://github.com/HuChanghong/learngit
git從安裝到應用的學習