git教程筆記

Git是什麼

Git能解決什麼問題

Git能解決什麼問題?答曰:版本控制。html

常常寫文檔的同窗應該比較清楚,對某個文檔修改了一點之後,又不想直接覆蓋,這樣的話,後面發現寫錯了,就恢復不回來。因此就複製出不少文件名不同,可是內容差很少的文件。git

這樣也不是不能夠,可是問題在於,Copy了不少份,太消耗空間。同時查找恢復也並不方便。github

因此咱們但願有這樣一種軟件,它能夠shell

  • 自動記錄文件的改動
  • 能夠團隊協做編輯

好比這樣windows

版本 文件名 用戶 說明 日期
1 service.doc 張三 刪除了軟件服務條款5 7/12 10:38
2 service.doc 張三 增長了License人數限制 7/12 18:09
3 service.doc 李四 財務部門調整了合同金額 7/13 9:51
4 service.doc 張三 延長了免費升級週期 7/14 15:17

其實僅僅是對Word文檔進行版本控制,我以爲有道雲協做就能夠了,可是它須要使用外網,並且不是利用Windows自帶的目錄,感受仍是不太方便。安全

分佈式版本控制平臺

其實版本控制器還有不少,好比CVS和SVN,可是它們都是集中式的控制系統。bash

所謂集中式,天然有個Master級別的角色,它能夠保存全部的版本庫。你們須要先從版本庫裏面得到最新的版本,修改之後再上傳。這樣Master天然就有了全部分支最新的版本了。服務器

缺點是必須聯網,是否是很相似與上面說到的有道雲筆記啊!app

那分佈式版本控制系統有啥區別呢?分佈式系統沒有Master這個角色,全部的終端一視同仁,每一個人都有一個完整的版本庫。那怎麼協做呢?只須要互相通訊,互相推送就能夠了。ssh

分佈式系統的優勢在於安全,一我的的電腦壞了,還有其餘人的電腦做爲備份嘛。

固然在實際應用的時候,通常不會有兩我的互相推送,仍是會引入一個中央服務器,可是它就相似於一個交換機,只是用來交互數據,沒有它你們也能夠在本地幹活。

並且Git還有強大的分支管理功能,仍是免費的。如今最快、最簡單也最流行的就是Git了。

安裝Git

  • Linux上安裝
sudo apt-get install git

配置

首先要進行全局設置:

$ git config --global user.name "Your Name"
$ git config --global user.email "email@example.com"

提交版本

建立版本庫

什麼是版本庫?就是倉庫,respository,能夠理解爲一個目錄,裏面的全部文件能夠被Git管理起來,裏面的文件修改、刪除都跟跟蹤到。

下面來建立版本庫,

在須要建立版本庫的地方里面打開cmder,輸入

git init

當前目錄下多了一個.git的目錄,這個目錄是Git來跟蹤管理版本庫的

某些文件不提交

有些時候須要把某些文件放到目錄中,可是又不能提交它。能夠在Git工做區創建一個.gitignore文件,裏面填充要忽略的文件名

咱們能夠經過.gitignore網站查看各類配置文件,組合一下便可用。

通常須要忽略那些文件呢?

  • 操做系統自動生成的文件或者編譯生成的文件。
  • 忽略敏感信息,好比密碼
    好比Python裏面,
# Windows:
Thumbs.db
ehthumbs.db
Desktop.ini

# Python:
*.py[cod]
*.so
*.egg
*.egg-info
dist
build

# My configurations:
db.ini
deploy_key_rsa

有的時候,想添加一個文件到Git,發現添加不了,多半是被忽略了。可使用

git add -f <文件>

也能夠看是哪條規則限制了這個文件的上傳

git check-ignore -v <文件>

將文件提交到版本庫裏面

全部的版本控制系統都只能跟蹤文本文件的改動,好比TXT文件、代碼等。

對於圖片、視頻、Word等都是二進制文件,雖然仍然能夠由版本控制系統管理,可是沒有辦法對比文件系統的變化。也就是說經過Cmder沒法對比兩個版本之間的差異。

因此使用Git主要仍是針對於代碼文件、TXT文件等進行版本控制,須要注意的是

使用windows進行編碼的時候,建議使用Notepad++將默認編碼設置爲UTF-8 without BOM

添加文件到Git倉庫,分兩步:

  • 第一步,使用命令git add .,注意,可反覆屢次使用,添加多個文件;
    要隨時掌握工做區的狀態,使用git status命令。
    若是git status告訴你有文件被修改過,用git diff readme.txt能夠查看修改內容。
    git diff HEAD -- readme.txt能夠看查看工做區和版本庫裏面最新版本的區別

  • 第二步,使用命令git commit -m "備註"進行正式提交。
    實際上每次執行git commit -m就保存了一次快照,相似於打遊戲的時候存一次檔。若是咱們想回退的話,能夠經過快照來進行恢復rollback
    可使用git log --pretty=oneline命令顯示從最近到最遠的提交日誌,以時間軸的形式顯示日誌提交。

版本回退

上面一章咱們講了,可使用git commit進行提交,而後使用git log --pretty=oneline查看有提交的版本。

$ git log --pretty=oneline
3628164fb26d48395383f8f31179f24e0882e1e0 append GPL
ea34578d5496d7dd233c827ed32a8cd576c5ee85 add distributed
cb926e7ea50ad11b8f9e909c05226233bf755030 wrote a readme file

其中相似3628164...882e1e0的是commit id(版本號),爲了保證多人提交的環境下,commit id不一樣,因此Git使用了SHA1計算出來的一個很是大的數字,用十六進制表示,這樣就能夠避免衝突了。

Git就會把每一個版本自動串成一條時間線

image.png

如何進行版本回退

首先,Git必須知道當前版本是哪一個版本,

  • HEAD表示當前版本,
  • 上一個版本就是HEAD^
  • 上上一個版本就是HEAD^^
  • 固然往上100個版本寫成HEAD~100

而後使用git reset開始回退

git reset --hard HEAD^

若是發現回退錯了,因此想回到最開始的版本。

  • 若是命令行窗口尚未被關掉,能夠順着往上找直到找到那個版本的ID是3628164...,因而就能夠指定回到將來的某個版本:
$ git reset --hard 3628164
  • 若是命令行窗口關閉了,可使用git reflog來查看執行commit命令時候的commit id。而後使用git reset

總結一下:
如今總結一下:

  • HEAD指向的版本就是當前版本,所以,Git容許咱們在版本的歷史之間穿梭,使用命令git reset --hard commit_id

  • 穿梭前,用git log能夠查看提交歷史,以便肯定要回退到哪一個版本。

  • 要重返將來,用git reflog查看命令歷史,以便肯定要回到將來的哪一個版本。

幾個概念

首先解釋幾個名詞:

  • 工做區:指的是創建了git的目錄,也就是平時咱們進行代碼編輯的地方
  • 版本庫:工做區有一個隱藏目錄.git,是Git的版本庫。
    版本庫裏面有暫存區(Stage)、分支(Master)以及指向分支的指針HEAD
    其中Git區別於其餘的版本控制系統的一個不一樣之處就是有了暫存區

git add命令實際上就是把要提交的全部修改放到暫存區(Stage),而後,執行git commit就能夠一次性把暫存區的全部修改提交到分支。

image.png

理解了這個,咱們來可以下的過程

第一次修改 -> git add -> 第二次修改 -> git commit

能夠發現第二次修改之後並無git add,也就是第二次修改的內容沒有放到暫存區,因此git commit不會把第第二次的修改提交了。

這就是Git比其餘版本控制系統優秀的地方,由於Git跟蹤管理的是修改,而不是文件

沒有提交到分支以前的撤銷

以前咱們說到了若是已經git commit到分支之後,要進行版本回退應該怎麼作。

可是若是咱們只是添加到了暫存區,甚至還沒提交到暫存區,此時應該如何撤銷呢?

  • 只是修改,沒有add到暫存區:
git checkout -- file

使用這個命令還能夠把誤刪的文件恢復回來

  • 已經add到暫存區,可是沒有commit
    • 首先使用git reset HEAD file回退到工做區。
    • 而後使用git checkout -- file把工做區的修改撤銷了。

總之,記住一點:git checkout -- 文件命令,撤銷的是工做中文件的修改,而git reset HEAD -- 文件命令,撤銷的是暫存區中文件的修改。

撤銷本地全部修改

git checkout . #本地全部修改的。沒有的提交的,都返回到原來的狀態
git stash  #把全部沒有提交的修改暫存到stash裏面。可用git stash pop回覆。
git reset --hard HEAD #返回到某個節點,不保留修改。

分支

分支有什麼用?每一個人能夠建立本身的分支,想提交就提交,直到完成全部的功能之後,一次性合併到原來的分支上,這樣能夠不影響別人工做。

Git好就好在切換分支只須要不到1s,比SVN等快不少。

建立分支

Git默認有一條主分支,即master分支,而HEAD指針實際上指向當前分支的,此時就是master
image.png

當建立新的分支後,Git新建了一個指針devHEAD指向dev,切換到了dev上了。而後後面的修改都是在dev上了,master指針不變。

image.png

當咱們在dev上把工做完成了,就能夠合併分支。方法就是直接把master指向dev當前的提交。

image.png

下面是具體用命令怎麼作

  • 建立dev分支並切換
$ git branch dev
$ git checkout dev#切換分支
  • 正常提交
  • 切換到master分支上
  • 合併指定分支dev當前master分支
git merge dev

此時有可能兩個分支都有提交,因此沒法自動合併,須要手動解決衝突,再提交
image.png

  • 刪除分支
$ git branch -d dev

分支策略

在實際團隊協做的時候,應該保證master很是穩定,只 是用來發布新的版本,平臺應該不在上面修改。

每一個人能夠常常生成一些dev分支, 在上面進行修改,當有必要的時候,再合併到主分支上便可。

場景一:Bug分支

每一個bug均可以經過一個新的臨時分支來修復,修復後,合併分支,而後將臨時分支刪除。

當你接到一個修復一個代號101的bug的任務時,能夠建立一個分支issue-101來修復它,可是dev上的工做只進行到一半,還無法提交,怎麼辦?

  • 可使用stash功能把現場存儲起來,以後能夠恢復
git stash
  • 而後建立Bug分支,進行修復
  • 切換到master上,合併,刪除分支
  • 如今應該回到dev分支繼續幹活了。恢復現場
    • git stash apply:恢復之後stash內容不刪除,須要再使用git stash drop
    • git stash pop:恢復的時候同時把stash的內容也刪除了。
      由於可能屢次保存現場,因此能夠先使用git stash list查看,而後恢復指定的stash
$ git stash apply stash@{0}

場景二:Feature分支

開發一個新feature,最好新建一個分支,可是還沒開發完的時候,收到通知取消此特性。

此時固然直接刪除就好,不過問題就在於分支尚未被合併,若是刪除能夠經過git branch -D <name>強行刪除。

使用標籤

發佈一個版本的時候,能夠先在版本庫裏面打一個tag。標籤其實就是版本庫的一個快照

既然有commit,爲何還要tag呢?

好比要將上週一的版本打包發佈,咱們知道commit id是一堆亂七八糟的數字,並很差查找,若是加上一個tag v1.2,就有了實際意義,能夠與某個commit綁在一塊兒,更好查找。

如何打標籤

  • 首先,切換到打標籤的分支上git branch
  • 使用git tag v1.l0建立一個標籤,使用git tag能夠查看全部標籤,標籤不是按照時間排序,而是按照字母排序
  • 若是要綁定歷史的 commit,能夠怎能先使用git log找到commit id
git tag v0.9  commit id
  • 能夠建立帶有說明的標籤
git tag -a v0.1  -m "version 0.1 released"  32321332

可使用 git show v0.1查看說明。

若是標籤打錯了,能改嗎?固然能。刪除便可。

$ git tag -d v0.1

由於建立的標籤都只存儲在本地,不會自動推送到遠程。因此,打錯的標籤能夠在本地安全刪除。

遠程倉庫

到如今爲止咱們已經學會了如何在本身的電腦上進行工做,本章則將講解如何把代碼託管到Gitee遠程倉庫來進行管理,這樣就能夠進行協做以及代碼的備份呢。

以前咱們只是在本身的電腦上搭一個Git倉庫,實際上也能夠分佈到不一樣的機器上,別的機器只要複製原始版本就行了,這樣就能夠保證你們都同樣。

因此徹底能夠搭一個Git服務器,而後全部的人都從服務器裏面複製一份到本身這邊,再把各自的提交推送到倉庫裏面,實現協做。

最著名的Git服務器當屬GitHub,不過在國內比較的慢,因此咱們使用中國版的GitHub——碼雲gitee.com

上傳公鑰

本地Git倉庫和GitHub倉庫之間的傳輸是經過SSH加密的,因此須要先上傳公鑰,想知道原理能夠點擊HTTPS

  • 首先建立SSH Key
    打開CMDer,輸入
ssh-keygen -t rsa -C "youremail@example.com"#須要把郵件地址換成你本身的郵件地址

而後一路回車
能夠經過everything搜索一下id_rsa.pub這個公鑰在那裏,而後使用Notepad++打開,複製全部的內容。
image.png

  • 在Gitee的設置裏面粘貼公鑰的內容。

image.png

爲何要SSH Key呢?
由於碼雲要識別這個推送確實是你本人乾的。

固然碼雲支持多個Key,若是有多個電腦,能夠創建多個Key

將代碼推送到遠端

若是要把代碼推送到遠端,有兩種場景,一是如今已經在本地創建了倉庫了,如今想在Gitee上一樣創建一個,而後合併便可。
另外一種是如今啥都沒幹,直接從Gitee上建一個,而後clone到本地便可。

首先在Gitee上創建一個新倉庫名字是articlespider
image.png

  • 若是已經在本地創建了倉庫
    image.png
    • 首先關聯遠程庫:git remote add origin git@server-name:path/repo-name.git
    • 使用命令git push -u origin master第一次推送master分支的全部內容;
    • 此後的提交只須要使用git push origin master
cd existing_git_repo
git remote add origin https://gitee.com/***/articlespider.git
git push -u origin master

若是在新建遠程倉庫的時候加上了README.MD,可是這個Readme.md又不在本地庫裏面,因此會報錯。能夠

$ git pull --rebase origin master

固然也能夠在本地根目錄新建一個Readme.md

  • 若是如今尚未創建倉庫,可使用git clone複製一個版本下來。
git clone git@gitee.com:****/articlespider.git

多人協做

建立了遠程倉庫之後,能夠進行多人協做。能夠將本地的分支推送到遠端,也能夠從遠端拉取

推送分支

遠程倉庫默認名稱是origin

可使用git push進行推送。

git push origin 分支

拉取分支

如今另外一我的須要在dev分支上作開發,首先應該先clone一份到本地。

git clone git@gitee.com:****/articlespider.git

當從遠程倉庫克隆的時候,Git自動把master與遠程的master對應起來。

查看遠程庫的信息git remote -v

此時只能看到master分支,若是也要在分支dev上開發的話,必須建立遠程origin的dev分支到本地,

git checkout -b dev origin/dev

而後就能夠繼續開發了。

那麼咱們怎麼與之協做呢?

  • 首先可使用git push origin <branch>推送本身的修改
  • 若是推送失敗,則遠程分支比本地的更新,須要先用git pull合併。
    若是提示no tracking information,說明連接關係沒有創建起來。使用
git branch --set-upstream <branch> origin/<branch>
  • 若是合併有衝突,則解決衝突,並在本地提交
  • 衝突解決以後,再用git push origin <branch>

推送標籤

由於建立的標籤都只存儲在本地,不會自動推送到遠程

若是要推送某個標籤到遠程,使用命令git push origin <tagname>
或者,一次性推送所有還沒有推送到遠程的本地標籤:

$ git push origin --tags

若是要刪除的話,首先須要先刪除本地的。

$ git tag -d v0.9

而後,從遠程刪除。

$ git push origin :refs/tags/v0.9

修改遠程庫的名字

咱們可能同時進行多個項目,他們都須要推送到遠端。好比learngit項目,如今要與遠程庫關聯

git remote add origin git@gitee.com:<your name>/learngit.git

若是報錯fatal: remote origin already exists.說明本地庫已經關聯了一個名叫origin的遠程庫

能夠先刪除

git remote rm origin

再關聯一個遠程庫gitee

git remote add gitee git@gitee.com:<gitee name>/learngit.git

此時遠程庫的名稱叫gitee,不叫origin。

若是要推送:

git push gitee master

配置別名

所謂配置別名其實就是配置命令的簡寫,好比使用git st表示git status等。

$ git config --global alias.st status#查看工做區狀態
$ git config --global alias.co checkout#切換分支,撤銷修改
$ git config --global alias.ci commit#提交
$ git config --global alias.br branch#分支
$ git config --global alias.unstage 'reset HEAD'#回退
$ git config --global alias.last 'log -1'#查看log
$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"

加上--global是針對當前用戶起做用的

搭建Git服務器

搭建服務器

須要準備一臺運行Ubuntu的機器

  • 安裝git :sudo apt-get install git
  • 建立git 用戶,用來運行git服務:sudo adduser git
  • 建立證書登陸
    收集全部須要登陸的用戶的公鑰,就是他們本身的id_rsa.pub文件,把全部公鑰導入到/home/git/.ssh/authorized_keys文件裏,一行一個。
  • 初始化git倉庫
    選定一個目錄做爲Git倉庫,假定是/srv/sample.git,在/srv目錄下輸入命令:
$ sudo git init --bare sample.git

這樣就會建立一個沒有工做區的裸倉庫,把全部者改成git

sudo chown -R git:git sample.git
  • 禁用shell登陸
    編輯/etc/passwd文件完成。找到相似下面的一行:
git:x:1001:1001:,,,:/home/git:/bin/bash

改成:

git:x:1001:1001:,,,:/home/git:/usr/bin/git-shell

這樣,git用戶能夠正常經過ssh使用git,但沒法登陸shell,由於咱們爲git用戶指定的git-shell每次一登陸就自動退出。

  • 克隆遠程倉庫:
$ git clone git@server:/srv/sample.git

總結

最後把全部的命令總結成一個表格

一級 二級 命令
提交代碼 新建倉庫 git init
提交到暫存區 git add .
提交到分支 git commit -m ""
查看 查看狀態 git status
查看提交記錄 git log --pretty=oneline
查看命令歷史 git reflog
對比 git diff HEAD -- readme.txt
標籤 git tag
遠端倉庫 git remote -v
版本控制 未提交到暫存區 git checkout .
已提交到暫存區 git reset HEAD file
已經提交到分支 git reset --hard <HEAD^>
分支 建立分支 git branch dev
切換分支 git checkout dev
合併 git merge dev
刪除分支 git branch -d dev
強行刪除 git branch -D dev
存儲現場 git stash
恢復現場 git stash pop
標籤 建立標籤 git tag v0.9
刪除標籤 git tag -d v0.8
推送遠程標籤 git push origin --tags
刪除遠程標籤 git push origin :refs/tags/v0.9
遠程倉庫 上傳公鑰 ssh-keygen -t rsa -C "youremail@example.com"
關聯遠程庫 git remote add origin https://gitee.com/***/articlespider.git
刪除遠程庫 git remote rm origin
第一次提交 git push -u origin master
普通提交 git push origin
拉取 git pull origin
多人協做 複製 git clone git@gitee.com:****/articlespider.git
建立遠端分支到本地 git checkout -b dev origin/dev
建立連接關係 git branch --set-upstream origin/
別名 查看log $git config --global alias.lg "log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)

參考

本文主要是根據Git教程整理獲得的,目的是幫助Git學習。

相關文章
相關標籤/搜索