1. 程式人生 > >git教程筆記

git教程筆記

當前 找到 分布式系統 狀態 創建分支 對比 user bug 打開

Git是什麽

Git能解決什麽問題

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

經常寫文檔的同學應該比較清楚,對某個文檔修改了一點以後,又不想直接覆蓋,這樣的話,後面發現寫錯了,就恢復不回來。所以就復制出很多文件名不一樣,但是內容差不多的文件。

這樣也不是不可以,但是問題在於,Copy了很多份,太消耗空間。同時查找恢復也並不方便。

所以我們希望有這樣一種軟件,它可以

  • 自動記錄文件的改動
  • 可以團隊協作編輯

比如這樣

版本 文件名 用戶 說明 日期
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,但是它們都是集中式的控制系統。

所謂集中式,自然有個Master級別的角色,它可以保存所有的版本庫。大家需要先從版本庫裏面獲得最新的版本,修改以後再上傳。這樣Master自然就有了所有分支最新的版本了。

缺點是必須聯網

,是不是很類似與上面說到的有道雲筆記啊!

那分布式版本控制系統有啥區別呢?分布式系統沒有Master這個角色,所有的終端一視同仁,每個人都有一個完整的版本庫。那怎麽協作呢?只需要互相通信,互相推送就可以了。

分布式系統的優點在於安全,一個人的電腦壞了,還有其他人的電腦作為備份嘛。

當然在實際應用的時候,一般不會有兩個人互相推送,還是會引入一個中央服務器,但是它就類似於一個交換機,只是用來交互數據,沒有它大家也可以在本地幹活。

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

安裝Git

  • Linux上安裝

    sudo apt-get install git
  • Windows上安裝
    參考【使用教程】CMDer,Window下CMD的替代者
    安裝Cmder即可,裏面就自帶了git功能。

配置

首先要進行全局設置:

$ git config --global user.name "Your Name"
$ git config --global user.email "[email protected]"

提交版本

創建版本庫

什麽是版本庫?就是倉庫,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就會把每個版本自動串成一條時間線

技術分享圖片

如何進行版本回退

首先,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就可以一次性把暫存區的所有修改提交到分支。

技術分享圖片

理解了這個,我們來可如下的過程

第一次修改 -> 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
技術分享圖片

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

技術分享圖片

當我們在dev上把工作完成了,就可以合並分支。方法就是直接把master指向dev當前的提交。

技術分享圖片

下面是具體用命令怎麽做

  • 創建dev分支並切換

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

    git merge dev
    此時有可能兩個分支都有提交,所以無法自動合並,需要手動解決沖突,再提交
    技術分享圖片
  • 刪除分支

    $ 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 "[email protected]"#需要把郵件地址換成你自己的郵件地址
    然後一路回車
    可以通過everything搜索一下id_rsa.pub這個公鑰在那裏,然後使用Notepad++打開,復制所有的內容。
    技術分享圖片
  • 在Gitee的設置裏面粘貼公鑰的內容。

技術分享圖片

為什麽要SSH Key呢?
因為碼雲要識別這個推送確實是你本人幹的。

當然碼雲支持多個Key,如果有多個電腦,可以建立多個Key

將代碼推送到遠端

如果要把代碼推送到遠端,有兩種場景,一是現在已經在本地建立了倉庫了,現在想在Gitee上同樣建立一個,然後合並即可。
另一種是現在啥都沒幹,直接從Gitee上建一個,然後clone到本地即可。

首先在Gitee上建立一個新倉庫名字是articlespider
技術分享圖片

  • 如果已經在本地建立了倉庫
    技術分享圖片
    • 首先關聯遠程庫: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 [email protected]:****/articlespider.git

多人協作

創建了遠程倉庫以後,可以進行多人協作。可以將本地的分支推送到遠端,也可以從遠端拉取

推送分支

遠程倉庫默認名稱是origin

可以使用git push進行推送。

git push origin 分支

拉取分支

現在另一個人需要在dev分支上做開發,首先應該先clone一份到本地。

git clone [email protected]:****/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 [email protected]:<your name>/learngit.git

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

可以先刪除

git remote rm origin

再關聯一個遠程庫gitee

git remote add gitee [email protected]:<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
分支 創建分支 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 "[email protected]"
關聯遠程庫 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 [email protected]:****/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學習。

git教程筆記