一個小時學會Git


最近要與部門同事一起做技術分享,我選擇了Git,因為Git 是一種在全球范圍都廣受歡迎的版本控制系統。在開發過程中,為了跟蹤代碼,文檔,項目等信息中的變化,版本控制變得前所未有的重要。

一、版本控制概要 工作區 暫存區 本地倉庫 遠程倉庫

1.1、什么是版本控制

版本控制(Revision control)是一種在開發的過程中用於管理我們對文件、目錄或工程等內容的修改歷史,方便查看更改歷史記錄,備份以便恢復以前的版本的軟件工程技術。

  • 實現跨區域多人協同開發
  • 追蹤和記載一個或者多個文件的歷史記錄
  • 組織和保護你的源代碼和文檔
  • 統計工作量
  • 並行開發、提高開發效率
  • 跟蹤記錄整個軟件的開發過程
  • 減輕開發人員的負擔,節省時間,同時降低人為錯誤

簡單說就是用於管理多人協同開發項目的技術

沒有進行版本控制或者版本控制本身缺乏正確的流程管理,在軟件開發過程中將會引入很多問題,如軟件代碼的一致性、軟件內容的冗余、軟件過程的事物性、軟件開發過程中的並發性、軟件源代碼的安全性,以及軟件的整合等問題。

1.2、常用術語

1)、倉庫(Repository)
受版本控制的所有文件修訂歷史的共享數據庫

2)、工作空間(Workspace)
本地硬盤或Unix 用戶帳戶上編輯的文件副本

3)、工作樹/區(Working tree)
工作區中包含了倉庫的工作文件。您可以修改的內容和提交更改作為新的提交到倉庫。

4)、暫存區(Staging area)
暫存區是工作區用來提交更改(commit)前可以暫存工作區的變化。

5)、索引(Index)
索引是暫存區的另一種術語。

6)、簽入(Checkin)
將新版本復制回倉庫

7)、簽出(Checkout)
從倉庫中將文件的最新修訂版本復制到工作空間

8)、提交(Commit)
對各自文件的工作副本做了更改,並將這些更改提交到倉庫

9)、沖突(Conflict)
多人對同一文件的工作副本進行更改,並將這些更改提交到倉庫

10)、合並(Merge)
將某分支上的更改聯接到此主干或同為主干的另一個分支

11)、分支(Branch)
從主線上分離開的副本,默認分支叫master

12)、鎖(Lock)
獲得修改文件的專有權限。

13)、頭(HEAD)
頭是一個象征性的參考,最常用以指向當前選擇的分支。

14)、修訂(Revision)
表示代碼的一個版本狀態。Git通過用SHA1 hash算法表示的ID來標識不同的版本。

15)、標記(Tags)
標記指的是某個分支某個特定時間點的狀態。通過標記,可以很方便的切換到標記時的狀態。

1.3、常見的版本控制器

主流的版本控制器有如下這些:

  • Git
  • SVN(Subversion)
  • CVS(Concurrent Versions System)
  • VSS(Micorosoft Visual SourceSafe)
  • TFS(Team Foundation Server)
  • Visual Studio Online

版本控制產品非常的多(Perforce、Rational ClearCase、RCS(GNU Revision Control System)、Serena Dimention、SVK、BitKeeper、Monotone、Bazaar、Mercurial、SourceGear Vault),現在影響力最大且使用最廣泛的是Git與SVN

1.4、版本控制分類

1.4.1、本地版本控制

記錄文件每次的更新,可以對每個版本做一個快照,或是記錄補丁文件,適合個人用,如RCS。

1.4.2、集中版本控制

所有的版本數據都保存在服務器上,協同開發者從服務器上同步更新或上傳自己的修改

所有的版本數據都存在服務器上,用戶的本地只有自己以前所同步的版本,如果不連網的話,用戶就看不到歷史版本,也無法切換版本驗證問題,或在不同分支工作。而且,所有數據都保存在單一的服務器上,有很大的風險這個服務器會損壞,這樣就會丟失所有的數據,當然可以定期備份。代表產品:SVN、CVS、VSS

1.4.3、分布式版本控制

所有版本信息倉庫全部同步到本地的每個用戶,這樣就可以在本地查看所有版本歷史,可以離線在本地提交,只需在連網時push到相應的服務器或其他用戶那里。由於每個用戶那里保存的都是所有的版本數據,只要有一個用戶的設備沒有問題就可以恢復所有的數據,但這增加了本地存儲空間的占用

1.5、Git與SVN最主要區別

SVN是集中式版本控制系統,版本庫是集中放在中央服務器的,而工作的時候,用的都是自己的電腦,所以首先要從中央服務器得到最新的版本,然后工作,完成工作后,需要把自己做完的活推送到中央服務器。集中式版本控制系統是必須聯網才能工作,對網絡帶寬要求較高。

 

Git是分布式版本控制系統,沒有中央服務器,每個人的電腦就是一個完整的版本庫,工作的時候不需要聯網了,因為版本都在自己電腦上。協同的方法是這樣的:比如說自己在電腦上改了文件A,其他人也在電腦上改了文件A,這時,你們兩之間只需把各自的修改推送給對方,就可以互相看到對方的修改了。

二、Git安裝與配置

2.1、什么是Git

Git是目前世界上最先進的分布式版本控制系統。

Git是免費、開源的

最初Git是為輔助 Linux 內核開發的,來替代 BitKeeper

作者:Linux和Git之父李納斯·托沃茲(Linus Benedic Torvalds)1969、芬蘭

優點:

  • 適合分布式開發,強調個體。
  • 公共服務器壓力和數據量都不會太大。
  • 速度快、靈活。
  • 任意兩個開發者之間可以很容易的解決沖突。
  • 離線工作。

缺點:

  • 模式上比SVN更加復雜。
  • 不符合常規思維。
  • 代碼保密性差,一旦開發者把整個庫克隆下來就可以完全公開所有代碼和版本信息。

官網https://git-scm.com/

源碼: https://github.com/git/git/

2.2、搭建Git工作環境

2.2.1、下載Git

打開 git官網,下載git對應操作系統的版本。

選擇版本:

這里我選擇下載64-bit Git for Windows Setup

2.2.2、安裝Git

選擇安裝配置信息

一直Next默認就好了,如果需要設置就要仔細讀一下安裝界面上的選項。

2.2.3、啟動Git

安裝成功后在開始菜單中會有Git項,菜單下有3個程序:

Git Bash:Unix與Linux風格的命令行,使用最多,推薦最多

與DOS風格的命令有些區別,不習慣可以選擇Git CMD

Git CMD:Windows風格的命令行

Git GUI:圖形界面的Git,不建議初學者使用,盡量先熟悉常用命令

點擊Create New Repository可以直接創建一個新的倉庫。

2.2.4、Linux與Mac OS安裝Git

Linux安裝Git:sudo apt-get install git 命令行就可以安裝了。

Mac OS安裝Git: https://git-scm.com/download/mac,下載雙擊.pkg安裝

2.2.5、Bash基本操作命令

~就是home

進入Bash默認位置,注意標題欄

1)、cd : 改變目錄。

  cd ~ 回Home(windows是當前用戶所在目錄)

  

2)、cd . . 回退到上一個目錄,直接cd進入默認目錄

3)、pwd : 顯示當前所在的目錄路徑。

4)、ls(ll): 都是列出當前目錄中的所有文件,只不過ll(兩個ll)列出的內容更為詳細。

5)、touch : 新建一個文件 如 touch index.js 就會在當前目錄下新建一個index.js文件。

6)、rm: 刪除一個文件, rm index.js 就會把index.js文件刪除。

7)、mkdir: 新建一個目錄,就是新建一個文件夾。

8)、rm -r : 刪除一個文件夾, rm -r src 刪除src目錄, 好像不能用通配符。

9)、mv 移動文件, mv index.html src index.html 是我們要移動的文件, src 是目標文件夾,當然, 這樣寫,必須保證文件和目標文件夾在同一目錄下。

10)、reset 重新初始化終端/清屏。

11)、clear 清屏。

12)、history 查看命令歷史。

13)、help 幫助。

14)、exit 退出。

15)、#表示注釋

16)、輸出與注釋

17)、創建文件

小於號:命令默認從鍵盤獲得的輸入,改成從文件,或者其它打開文件以及設備輸入

>> 是追加內容

> 是覆蓋原有內容

 18、顯示文件內容 cat

 

2.3、Git配置 - git config

2.3.1、查看配置 - git config -l

使用git config -l 可以查看現在的git環境詳細配置

查看不同級別的配置文件:

#查看系統config
git config --system --list
  
#查看當前用戶(global)配置
git config --global  --list
 
#查看當前倉庫配置信息
git config --local  --list

2.3.2、Git配置文件分類

Windows系統中,Git在$HOME目錄中查找.gitconfig文件(一般位於C:\Documents and Settings\$USER下)

Git相關的配置文件有三個:

1)、 /etc/gitconfig:包含了適用於系統所有用戶和所有項目的值。(Win:C:\Program Files\Git\mingw64\etc\gitconfig) --system 系統級

 

2)、~/.gitconfig:只適用於當前登錄用戶的配置。(Win:C:\Users\Administrator\.gitconfig)  --global 全局

3)、位於git項目目錄中的.git/config:適用於特定git項目的配置。(Win:C:\gitProject) --local當前項目

注意:對於同一配置項,三個配置文件的優先級是1<2<3

這里可以直接編輯配置文件,通過命令設置后會響應到這里。

2.3.3、設置用戶名與郵箱(用戶標識,必要)

當你安裝Git后首先要做的事情是設置你的用戶名稱和e-mail地址。這是非常重要的,因為每次Git提交都會使用該信息。它被永遠的嵌入到了你的提交中:

   $ git config --global user.name "zhangguo"  #名稱
   $ git config --global user.email zhangguo@qq.com   #郵箱

只需要做一次這個設置,如果你傳遞了--global 選項,因為Git將總是會使用該信息來處理你在系統中所做的一切操作。如果你希望在一個特定的項目中使用不同的名稱或e-mail地址,你可以在該項目中運行該命令而不要--global選項。 總之--global為全局配置,不加為某個項目的特定配置

2.3.4、添加或刪除配置項

1)、添加配置項 
git config [--local|--global|--system]  section.key value
[--local|--global|--system]  #可選的,對應本地,全局,系統不同級別的設置,請看2.3.2
section.key #區域下的鍵
value #對應的值

--local 項目級

--global 當前用戶級

--system 系統級 

例如我們要在student區域下添加一個名稱為height值為198的配置項,執行結果如下:

2)、刪除配置項 

git config [--local|--global|--system] --unset section.key

 將系統級的height配置項移除

2.3.5、更多配置項

git config --global color.ui true   #打開所有的默認終端着色
git config --global alias.ci commit   #別名 ci 是commit的別名
[alias]  
co = checkout  
ci = commit  
st = status  
pl = pull  
ps = push  
dt = difftool  
l = log --stat  
cp = cherry-pick  
ca = commit -a  
b = branch 

user.name  #用戶名
user.email  #郵箱
core.editor  #文本編輯器  
merge.tool  #差異分析工具  
core.paper "less -N"  #配置顯示方式  
color.diff true  #diff顏色配置  
alias.co checkout  #設置別名
git config user.name  #獲得用戶名
git config core.filemode false  #忽略修改權限的文件  

所有config命令參數

語法: git config [<options>]        
        
文件位置        
    --global                  #use global config file 使用全局配置文件
    --system                  #use system config file 使用系統配置文件
    --local                   #use repository config file    使用存儲庫配置文件
    -f, --file <file>         #use given config file    使用給定的配置文件
    --blob <blob-id>          #read config from given blob object    從給定的對象中讀取配置
        
動作        
    --get                     #get value: name [value-regex]    獲得值:[值]名[正則表達式]
    --get-all                 #get all values: key [value-regex]    獲得所有值:[值]名[正則表達式]
    --get-regexp          #get values for regexp: name-regex [value-regex]    得到的值根據正則
    --get-urlmatch            #get value specific for the URL: section[.var] URL    為URL獲取特定的值
    --replace-all             #replace all matching variables: name value [value_regex]    替換所有匹配的變量:名稱值[ value_regex ]
    --add                     #add a new variable: name value    添加一個新變量:name值
    --unset                   #remove a variable: name [value-regex]    刪除一個變量名[值]:正則表達式
    --unset-all               #remove all matches: name [value-regex]    刪除所有匹配的正則表達式:名稱[值]
    --rename-section          #rename section: old-name new-name    重命名部分:舊名稱 新名稱
    --remove-section          #remove a section: name    刪除部分:名稱
    -l, --list                #list all    列出所有
    -e, --edit            #open an editor    打開一個編輯器
    --get-color               #find the color configured: slot [default]    找到配置的顏色:插槽[默認]
    --get-colorbool           #find the color setting: slot [stdout-is-tty]    發現顏色設置:槽[ stdout是TTY ]
        
類型        
    --bool                    #value is "true" or "false"    值是“真”或“假”。
    --int                     #value is decimal number    值是十進制數。
    --bool-or-int             #value is --bool or --int    值--布爾或int
    --path                    #value is a path (file or directory name)    值是路徑(文件或目錄名)
        
其它        
    -z, --null                #terminate values with NUL byte    終止值與null字節
    --name-only               #show variable names only    只顯示變量名
    --includes                #respect include directives on lookup    尊重包括查找指令
    --show-origin             #show origin of config (file, standard input, blob, command line)    顯示配置(文件、標准輸入、數據塊、命令行)的來源

三、Git理論基礎

3.1、工作區域

Git本地有三個工作區域:工作目錄(Working Directory)、暫存區(Stage/Index)、資源庫(Repository或Git Directory)。如果在加上遠程的git倉庫(Remote Directory)就可以分為四個工作區域。文件在這四個區域之間的轉換關系如下:

  • Workspace:工作區,就是你平時存放項目代碼的地方
  • Index / Stage:暫存區,用於臨時存放你的改動,事實上它只是一個文件,保存即將提交到文件列表信息
  • Repository:倉庫區(或本地倉庫),就是安全存放數據的位置,這里面有你提交到所有版本的數據。其中HEAD指向最新放入倉庫的版本
  • Remote:遠程倉庫,托管代碼的服務器,可以簡單的認為是你項目組中的一台電腦用於遠程數據交換

本地的三個區域確切的說應該是git倉庫中HEAD指向的版本

  • Directory:使用Git管理的一個目錄,也就是一個倉庫,包含我們的工作空間和Git的管理空間。
  • WorkSpace:需要通過Git進行版本控制的目錄和文件,這些目錄和文件組成了工作空間。
  • .git:存放Git管理信息的目錄,初始化倉庫的時候自動創建。
  • Index/Stage:暫存區,或者叫待提交更新區,在提交進入repo之前,我們可以把所有的更新放在暫存區。
  • Local Repo:本地倉庫,一個存放在本地的版本庫;HEAD會只是當前的開發分支(branch)。
  • Stash:隱藏,是一個工作狀態保存棧,用於保存/恢復WorkSpace中的臨時狀態。

3.2、工作流程

git的工作流程一般是這樣的:

1、在工作目錄中添加、修改文件;

2、將需要進行版本管理的文件放入暫存區域;

3、將暫存區域的文件提交到git倉庫。

因此,git管理的文件有三種狀態:已修改(modified),已暫存(staged),已提交(committed)

3.3、圖解教程

個人認為Git的原理相比別的版本控制器還是復雜一些的,有一份圖解教程比較直觀:

圖解教程英文原版

圖解教程中文版

四、Git操作

4.1、創建工作目錄與常用指令

工作目錄(WorkSpace)一般就是你希望Git幫助你管理的文件夾,可以是你項目的目錄,也可以是一個空目錄,建議不要有中文。

日常使用只要記住下圖6個命令:

4.2、獲得GIT倉庫

創建本地倉庫的方法有兩種:一種是創建全新的倉庫,另一種是克隆遠程倉庫。

4.2.1、創建全新倉庫

需要用GIT管理的項目的根目錄執行:

# 在當前目錄新建一個Git代碼庫
$ git init

執行:

結果:

 

執行后可以看到,僅僅在項目目錄多出了一個.git目錄,關於版本等的所有信息都在這個目錄里面。

當然如果使用如下命令,可以把創建目錄與倉庫一起完成:

# 新建一個目錄,將其初始化為Git代碼庫
$ git init [project-name]

 執行命令與運行結果:

4.2.2、克隆遠程倉庫

 另一種方式是克隆遠程目錄,由於是將遠程服務器上的倉庫完全鏡像一份至本地,而不是取某一個特定版本,所以用clone而不是checkout,語法格式如下:

# 克隆一個項目和它的整個代碼歷史(版本信息)
$ git clone [url]

執行:

比如我們要從克隆的遠程倉庫托管在github上,地址為:https://github.com/zhangguo5/SuperPlus.git,這是一個公開的項目

結果:

4.3、GIT文件操作

版本控制就是對文件的版本控制,要對文件進行修改、提交等操作,首先要知道文件當前在什么狀態,不然可能會提交了現在還不想提交的文件,或者要提交的文件沒提交上。GIT不關心文件兩個版本之間的具體差別,而是關心文件的整體是否有改變,若文件被改變,在添加提交時就生成文件新版本的快照,而判斷文件整體是否改變的方法就是用SHA-1算法計算文件的校驗和

4.3.1、文件4種狀態

  • Untracked: 未跟蹤, 此文件在文件夾中, 但並沒有加入到git庫, 不參與版本控制. 通過git add 狀態變為Staged.

  • Unmodify: 文件已經入庫, 未修改, 即版本庫中的文件快照內容與文件夾中完全一致. 這種類型的文件有兩種去處, 如果它被修改, 而變為Modified. 如果使用git rm移出版本庫, 則成為Untracked文件

  • Modified: 文件已修改, 僅僅是修改, 並沒有進行其他的操作. 這個文件也有兩個去處, 通過git add可進入暫存staged狀態, 使用git checkout 則丟棄修改過, 返回到unmodify狀態, 這個git checkout即從庫中取出文件, 覆蓋當前修改

  • Staged: 暫存狀態. 執行git commit則將修改同步到庫中, 這時庫中的文件和本地文件又變為一致, 文件為Unmodify狀態. 執行git reset HEAD filename取消暫存, 文件狀態為Modified

4.3.2、查看文件狀態

上面說文件有4種狀態,通過如下命令可以查看到文件的狀態:

#查看指定文件狀態
git status [filename]

#查看所有文件狀態
git status

命令:

結果:

foo.htm文件的狀態為untracked(未跟蹤),提示通過git add可以暫存

GIT在這一點做得很好,在輸出每個文件狀態的同時還說明了怎么操作,像上圖就有怎么暫存、怎么跟蹤文件、怎么取消暫存的說明。

4.3.3、添加文件與目錄

工作區(Working Directory)就是你在電腦里能看到的目錄。

版本庫(Repository)工作區有一個隱藏目錄.git,這個不算工作區,而是Git的版本庫。

Git的版本庫里存了很多東西,其中最重要的就是稱為stage(或者叫index)的暫存區,還有Git為我們自動創建的第一個分支master,以及指向master的一個指針叫HEAD

將untracked狀態的文件添加到暫存區,語法格式如下:

# 添加指定文件到暫存區
$ git add [file1] [file2] ...

# 添加指定目錄到暫存區,包括子目錄
$ git add [dir]

# 添加當前目錄的所有文件到暫存區
$ git add .

執行:

4.3.4、移除文件與目錄(撤銷add)

當執行如下命令時,會直接從暫存區刪除文件,工作區則不做出改變

#直接從暫存區刪除文件,工作區則不做出改變
git rm --cached <file>

執行命令

通過重寫目錄樹移除add文件:

#如果已經用add 命令把文件加入stage了,就先需要從stage中撤銷
git reset HEAD <file>...

當執行 “git reset HEAD” 命令時,暫存區的目錄樹會被重寫,被 master 分支指向的目錄樹所替換,但是工作區不受影響。

示例:把f1.txt文件從暫存區撤回工作區

移除所有未跟蹤文件

#移除所有未跟蹤文件
#一般會加上參數-df,-d表示包含目錄,-f表示強制清除。
git clean [options] 

示例:

移除前:

執行移除:

移除后:

#只從stage中刪除,保留物理文件
git rm --cached readme.txt 

#不但從stage中刪除,同時刪除物理文件
git rm readme.txt 

#把a.txt改名為b.txt
git mv a.txt b.txt 

當執行提交操作(git commit)時,暫存區的目錄樹寫到版本庫(對象庫)中,master 分支會做相應的更新。即 master 指向的目錄樹就是提交時暫存區的目錄樹。

當執行 “git reset HEAD” 命令時,暫存區的目錄樹會被重寫,被 master 分支指向的目錄樹所替換,但是工作區不受影響。

當執行 “git rm –cached <file>” 命令時,會直接從暫存區刪除文件,工作區則不做出改變。

當執行 “git checkout .” 或者 “git checkout — <file>” 命令時,會用暫存區全部或指定的文件替換工作區的文件。這個操作很危險,會清除工作區中未添加到暫存區的改動。

當執行 “git checkout HEAD .” 或者 “git checkout HEAD <file>” 命令時,會用 HEAD 指向的 master 分支中的全部或者部分文件替換暫存區和以及工作區中的文件。這個命令也是極具危險性的,因為不但會清除工作區中未提交的改動,也會清除暫存區中未提交的改 動。

4.3.5、查看文件修改后的差異

git diff用於顯示WorkSpace中的文件和暫存區文件的差異

用"git status"只能查看對哪些文件做了改動,如果要看改動了什么,可以用:

#查看文件修改后的差異
git diff [files]

命令:

 ---a表示修改之前的文件,+++b表示修改后的文件

#比較暫存區的文件與之前已經提交過的文件
git diff --cached

也可以把WorkSpace中的狀態和repo中的狀態進行diff,命令如下:

#比較repo與工作空間中的文件差異
git diff HEAD~n

4.3.6、簽出

如果倉庫中已經存在文件f4.txt,在工作區中對f4修改了,如果想撤銷可以使用checkout,簽出覆蓋

檢出命令git checkout是git最常用的命令之一,同時也是一個很危險的命令,因為這條命令會重寫工作區

語法:

#用法一
git checkout [-q] [<commit>] [--] <paths>...
#用法二
git checkout [<branch>]
#用法三
git checkout [-m] [[-b]--orphan] <new_branch>] [<start_point>]

<commit>是可選項,如果省略則相當於從暫存區(index)進行檢出

$ git checkout branch
#檢出branch分支。要完成圖中的三個步驟,更新HEAD以指向branch分支,以及用branch  指向的樹更新暫存區和工作區。

$ git checkout
#匯總顯示工作區、暫存區與HEAD的差異。

$ git checkout HEAD
#同上

$ git checkout -- filename
#用暫存區中filename文件來覆蓋工作區中的filename文件。相當於取消自上次執行git add filename以來(如果執行過)的本地修改。

$ git checkout branch -- filename
#維持HEAD的指向不變。用branch所指向的提交中filename替換暫存區和工作區中相   應的文件。注意會將暫存區和工作區中的filename文件直接覆蓋。

$ git checkout -- . 或寫作 git checkout .
#注意git checkout 命令后的參數為一個點(“.”)。這條命令最危險!會取消所有本地的  #修改(相對於暫存區)。相當於用暫存區的所有文件直接覆蓋本地文件,不給用戶任何確認的機會!

$ git checkout commit_id -- file_name
#如果不加commit_id,那么git checkout -- file_name 表示恢復文件到本地版本庫中最新的狀態。

示例: 

4.3.6、忽略文件

有些時候我們不想把某些文件納入版本控制中,比如數據庫文件,臨時文件,設計文件等

在主目錄下建立".gitignore"文件,此文件有如下規則:

  1. 忽略文件中的空行或以井號(#)開始的行將會被忽略。
  2. 可以使用Linux通配符。例如:星號(*)代表任意多個字符,問號(?)代表一個字符,方括號([abc])代表可選字符范圍,大括號({string1,string2,...})代表可選的字符串等。
  3. 如果名稱的最前面有一個感嘆號(!),表示例外規則,將不被忽略。
  4. 如果名稱的最前面是一個路徑分隔符(/),表示要忽略的文件在此目錄下,而子目錄中的文件不忽略。
  5. 如果名稱的最后面是一個路徑分隔符(/),表示要忽略的是此目錄下該名稱的子目錄,而非文件(默認文件或目錄都忽略)。

如:

#為注釋
*.txt #忽略所有 .txt結尾的文件
!lib.txt #但lib.txt除外
/temp #僅忽略項目根目錄下的TODO文件,不包括其它目錄temp
build/ #忽略build/目錄下的所有文件
doc/*.txt #會忽略 doc/notes.txt 但不包括 doc/server/arch.txt

更多規則請點這里

示例:

創建一個.gitignore文件忽視所有的日志文件

查看狀態:

從上圖中可以看出2個日志文件並沒有添加到暫存區,直接被忽視了。

針對各種語言與項目的Git忽視文件: https://github.com/kaedei/gitignore   https://github.com/github/gitignore

通用的java忽視文件:

# Compiled class file
*.class

# Log file
*.log

# BlueJ files
*.ctxt

# Mobile Tools for Java (J2ME)
.mtj.tmp/

# Package Files #
*.jar
*.war
*.ear
*.zip
*.tar.gz
*.rar

# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*

通用的Visual Studio開發項目忽視文件:

## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
##
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore

# User-specific files
*.suo
*.user
*.userosscache
*.sln.docstates

# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs

# Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
[Rr]eleases/
x64/
x86/
bld/
[Bb]in/
[Oo]bj/
[Ll]og/

# Visual Studio 2015 cache/options directory
.vs/
# Uncomment if you have tasks that create the project's static files in wwwroot
#wwwroot/

# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*

# NUNIT
*.VisualState.xml
TestResult.xml

# Build Results of an ATL Project
[Dd]ebugPS/
[Rr]eleasePS/
dlldata.c

# Benchmark Results
BenchmarkDotNet.Artifacts/

# .NET Core
project.lock.json
project.fragment.lock.json
artifacts/
**/Properties/launchSettings.json

*_i.c
*_p.c
*_i.h
*.ilk
*.meta
*.obj
*.pch
*.pdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*.log
*.vspscc
*.vssscc
.builds
*.pidb
*.svclog
*.scc

# Chutzpah Test files
_Chutzpah*

# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opendb
*.opensdf
*.sdf
*.cachefile
*.VC.db
*.VC.VC.opendb

# Visual Studio profiler
*.psess
*.vsp
*.vspx
*.sap

# TFS 2012 Local Workspace
$tf/

# Guidance Automation Toolkit
*.gpState

# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings.user

# JustCode is a .NET coding add-in
.JustCode

# TeamCity is a build add-in
_TeamCity*

# DotCover is a Code Coverage Tool
*.dotCover

# AxoCover is a Code Coverage Tool
.axoCover/*
!.axoCover/settings.json

# Visual Studio code coverage results
*.coverage
*.coveragexml

# NCrunch
_NCrunch_*
.*crunch*.local.xml
nCrunchTemp_*

# MightyMoose
*.mm.*
AutoTest.Net/

# Web workbench (sass)
.sass-cache/

# Installshield output folder
[Ee]xpress/

# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html

# Click-Once directory
publish/

# Publish Web Output
*.[Pp]ublish.xml
*.azurePubxml
# Note: Comment the next line if you want to checkin your web deploy settings,
# but database connection strings (with potential passwords) will be unencrypted
*.pubxml
*.publishproj

# Microsoft Azure Web App publish settings. Comment the next line if you want to
# checkin your Azure Web App publish settings, but sensitive information contained
# in these scripts will be unencrypted
PublishScripts/

# NuGet Packages
*.nupkg
# The packages folder can be ignored because of Package Restore
**/packages/*
# except build/, which is used as an MSBuild target.
!**/packages/build/
# Uncomment if necessary however generally it will be regenerated when needed
#!**/packages/repositories.config
# NuGet v3's project.json files produces more ignorable files
*.nuget.props
*.nuget.targets

# Microsoft Azure Build Output
csx/
*.build.csdef

# Microsoft Azure Emulator
ecf/
rcf/

# Windows Store app package directories and files
AppPackages/
BundleArtifacts/
Package.StoreAssociation.xml
_pkginfo.txt
*.appx

# Visual Studio cache files
# files ending in .cache can be ignored
*.[Cc]ache
# but keep track of directories ending in .cache
!*.[Cc]ache/

# Others
ClientBin/
~$*
*~
*.dbmdl
*.dbproj.schemaview
*.jfm
*.pfx
*.publishsettings
orleans.codegen.cs

# Since there are multiple workflows, uncomment next line to ignore bower_components
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
#bower_components/

# RIA/Silverlight projects
Generated_Code/

# Backup & report files from converting an old project file
# to a newer Visual Studio version. Backup files are not needed,
# because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm

# SQL Server files
*.mdf
*.ldf
*.ndf

# Business Intelligence projects
*.rdl.data
*.bim.layout
*.bim_*.settings

# Microsoft Fakes
FakesAssemblies/

# GhostDoc plugin setting file
*.GhostDoc.xml

# Node.js Tools for Visual Studio
.ntvs_analysis.dat
node_modules/

# Typescript v1 declaration files
typings/

# Visual Studio 6 build log
*.plg

# Visual Studio 6 workspace options file
*.opt

# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
*.vbw

# Visual Studio LightSwitch build output
**/*.HTMLClient/GeneratedArtifacts
**/*.DesktopClient/GeneratedArtifacts
**/*.DesktopClient/ModelManifest.xml
**/*.Server/GeneratedArtifacts
**/*.Server/ModelManifest.xml
_Pvt_Extensions

# Paket dependency manager
.paket/paket.exe
paket-files/

# FAKE - F# Make
.fake/

# JetBrains Rider
.idea/
*.sln.iml

# CodeRush
.cr/

# Python Tools for Visual Studio (PTVS)
__pycache__/
*.pyc

# Cake - Uncomment if you are using it
# tools/**
# !tools/packages.config

# Tabs Studio
*.tss

# Telerik's JustMock configuration file
*.jmconfig

# BizTalk build output
*.btp.cs
*.btm.cs
*.odx.cs
*.xsd.cs
View Code

idea忽視文件:

.idea/
*.iml
out/
gen/
idea-gitignore.jar
resources/templates.list
resources/gitignore/*
build/
build.properties
junit*.properties
IgnoreLexer.java~
.gradle

/verification

 

4.3.7、提交

通過add只是將文件或目錄添加到了index暫存區,使用commit可以實現將暫存區的文件提交到本地倉庫。

# 提交暫存區到倉庫區
$ git commit -m [message]

# 提交暫存區的指定文件到倉庫區
$ git commit [file1] [file2] ... -m [message]

# 提交工作區自上次commit之后的變化,直接到倉庫區,跳過了add,對新文件無效
$ git commit -a

# 提交時顯示所有diff信息
$ git commit -v

# 使用一次新的commit,替代上一次提交
# 如果代碼沒有任何新變化,則用來改寫上一次commit的提交信息
$ git commit --amend -m [message]

# 重做上一次commit,並包括指定文件的新變化
$ git commit --amend [file1] [file2] ...

示例:

提交前的狀態

提交:

提交后的狀態:

從上圖中可以看出暫存區中沒有了bar.htm

修訂提交

如果我們提交過后發現有個文件改錯了,或者只是想修改提交說明,這時可以對相應文件做出修改,將修改過的文件通過"git add"添加到暫存區,然后執行以下命令:

#修訂提交
git commit --amend

撤銷提交(commit)

原理就是放棄工作區和index的改動,同時HEAD指針指向前一個commit對象

#撤銷上一次的提交
git reset --hard HEAD~1

 要通過git log查看提交日志,也可直接指定提交編號或序號

示例:

撤銷提交
git revert <commit-id>
這條命令會把指定的提交的所有修改回滾,並同時生成一個新的提交。

4.3.8、日志與歷史

查看提交日志可以使用git log指令,語法格式如下:

#查看提交日志
git log [<options>] [<revision range>] [[\--] <path>…?]

示例:

"git log --graph"以圖形化的方式顯示提交歷史的關系,這就可以方便地查看提交歷史的分支信息,當然是控制台用字符畫出來的圖形。

"git log -1"則表示顯示1行。

使用history可以查看您在bash下輸入過的指令:

幾乎所有輸入過的都被記錄下來的,不愧是做版本控制的。

查看所有分支日志

"git reflog"中會記錄這個倉庫中所有的分支的所有更新記錄,包括已經撤銷的更新。

4.3.9、查看文件列表

使用git ls-files指令可以查看指定狀態的文件列表,格式如下:

#查看指定狀態的文件
git ls-files [-z] [-t] [-v] (--[cached|deleted|others|ignored|stage|unmerged|killed|modified])* (-[c|d|o|i|s|u|k|m])*

示例:

4.3.10、撤銷更新

1)、撤銷暫存區更新

使用"git add"把更新提交到了暫存區。這時"git status"的輸出中提示我們可以通過"git reset HEAD <file>..."把暫存區的更新移出到WorkSpace中

示例:f6已經提交,工作區修改,暫存區修改,撤銷

2)、撤銷本地倉庫更新

使用git log查看提交日志

撤銷提交有兩種方式:使用HEAD指針使用commit id

在Git中,有一個HEAD指針指向當前分支中最新的提交。當前版本,我們使用"HEAD^",那么再錢一個版本可以使用"HEAD^^",如果想回退到更早的提交,可以使用"HEAD~n"。(也就是,HEAD^=HEAD~1,HEAD^^=HEAD~2)

git reset --hard HEAD^
git reset --hard HEAD~1
git reset --59cf9334cf957535cb328f22a1579b84db0911e5

示例:回退到添加f6

回退前:

回退后:

 

現在又想恢復被撤銷的提交可用"git reflog"查看倉庫中所有的分支的所有更新記錄,包括已經撤銷的更新,撤銷方法與前面一樣。

git reset --hard HEAD@{7}
git reset --hard e0e79d7

--hard:撤銷並刪除相應的更新

--soft:撤銷相應的更新,把這些更新的內容放到Stage中

4.3.11、刪除文件

1)、刪除未跟蹤文件

如果文件還是未跟蹤狀態,直接刪除文件就可了,bash中使用rm可以刪除文件,示例如下:

2)、刪除已提交文件

 

-f 強制刪除,物理刪除了,同時刪除工作區和暫存區中的文件

撤銷刪除:

#to discard changes in working directory
git checkout -- <file>...

3)、刪除暫存區的文件,不刪除工作區的文件

 

使用git reset HEAD <file>...同樣可以實現上面的功能

4.3.12、文件操作小結

 Git很強大,很靈活,這是毋庸置疑的。但也正因為它的強大造成了它的復雜,因此會有很多奇奇怪怪的問題出現,多用就好了。

4.4、GIT分支

分支在GIT中相對較難

分支就是科幻電影里面的平行宇宙,當你正在電腦前努力學習Git的時候,另一個你正在另一個平行宇宙里努力學習SVN。

如果兩個平行宇宙互不干擾,那對現在的你也沒啥影響。不過,在某個時間點,兩個平行宇宙合並了,結果,你既學會了Git又學會了SVN!

分支在實際中有什么用呢?假設你准備開發一個新功能,但是需要兩周才能完成,第一周你寫了50%的代碼,如果立刻提交,由於代碼還沒寫完,不完整的代碼庫會導致別人不能干活了。如果等代碼全部寫完再一次提交,又存在丟失每天進度的巨大風險。

現在有了分支,就不用怕了。你創建了一個屬於你自己的分支,別人看不到,還繼續在原來的分支上正常工作,而你在自己的分支上干活,想提交就提交,直到開發完畢后,再一次性合並到原來的分支上,這樣,既安全,又不影響別人工作。

Git分支的速度非常快。

截止到目前,只有一條時間線,在Git里,這個分支叫主分支,即master分支。HEAD嚴格來說不是指向提交,而是指向master,master才是指向提交的,所以,HEAD指向的就是當前分支。

特性分支的圖示

git分支中常用指令:

# 列出所有本地分支
$ git branch

# 列出所有遠程分支
$ git branch -r

# 列出所有本地分支和遠程分支
$ git branch -a

# 新建一個分支,但依然停留在當前分支
$ 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]

4.4.1、新建分支與切換分支

每次提交,Git都把它們串成一條時間線,這條時間線就是一個分支。截止到目前,只有一條時間線,在Git里,這個分支叫主分支,即master分支。HEAD嚴格來說不是指向提交,而是指向master,master才是指向提交的,所以,HEAD指向的就是當前分支。
一開始的時候,master分支是一條線,Git用master指向最新的提交,再用HEAD指向master,就能確定當前分支,以及當前分支的提交點:

每次提交,master分支都會向前移動一步,這樣,隨着你不斷提交,master分支的線也越來越長:

默認分支是這樣的,master是主分支

git-br-initial

1)、新建一個分支,但依然停留在當前分支,使用:$ git branch [branch-name]

切換分支到dev1后的結果:

關於分支廖雪峰解釋的比較清楚,我們引用一下

當我們創建新的分支,例如dev時,Git新建了一個指針叫dev,指向master相同的提交,再把HEAD指向dev,就表示當前分支在dev上:

git-br-create

你看,Git創建一個分支很快,因為除了增加一個dev指針,改改HEAD的指向,工作區的文件都沒有任何變化!

不過,從現在開始,對工作區的修改和提交就是針對dev分支了,比如新提交一次后,dev指針往前移動一步,而master指針不變:

git-br-dev-fd

假如我們在dev上的工作完成了,就可以把dev合並到master上。Git怎么合並呢?最簡單的方法,就是直接把master指向dev的當前提交,就完成了合並:

git-br-ff-merge

所以Git合並分支也很快!就改改指針,工作區內容也不變!

合並完分支后,甚至可以刪除dev分支。刪除dev分支就是把dev指針給刪掉,刪掉后,我們就剩下了一條master分支:

git-br-rm

動畫演示:

2)、切換分支,git branch <name>,如果name為-則為上一個分支

切換為上一個分支

3)、新建一個分支,並切換到該分支,$ git checkout -b [branch]

4)、新建一個分支,指向指定commit使用命令:$ git branch [branch] [commit]

 

上面創建了dev3分支且指向了master中首次提交的位置,切換到dev3查看日志如下:

master上本來有兩個提交記錄的,此時的dev3指向的是第1次提交的位置

 5)、新建一個分支,與指定的遠程分支建立追蹤關系使用命令:$ git branch --track [branch] [remote-branch]

4.4.2、查看分支

1)、列出所有本地分支使用$ git branch

2)、列表所有遠程分支使用$ git branch -r

3)、列出所有本地分支和遠程分支使用$ git branch -a

4.4.3、分支合並

合並指定分支到當前分支使用指令$ git merge [branch]

這里的合並分支就是對分支的指針操作,我們先創建一個分支再合並到主分支:

這里的file11.txt主分支與dev6的內容現在是不同的,因為在dev6中已被修改過,我們可以使用指令查看:

現在我們將dev6合並到主分支中去,從下圖中可以看出dev6中有一次提交,而master並沒有

合並后在master上查看file11.txt文件內容與dev6上的內容就一樣了,合並后dev6中多出的提交在master也擁有了。

4.4.4、解決沖突

如果同一個文件在合並分支時都被修改了則會引起沖突,如下所示:

提交前兩個分支的狀態

在dev6分支中同樣修改file11.txt

dev6與master分支中file11.txt文件都被修改且提交了,現在合並分支

提示沖突,現在我們看看file11.txt在master分支中的狀態

Git用<<<<<<<,=======,>>>>>>>標記出不同分支的內容,其中<<<HEAD是指主分支修改的內容,>>>>>dev6 是指dev6上修改的內容

解決的辦法是我們可以修改沖突文件后重新提交,請注意當前的狀態產master | MERGING:

重新提交后沖突解決:

手動解決完沖突后就可以把此文件添 加到索引(index)中去,用git commit命令來提交,就像平時修改了一個文件 一樣。

git log --graph命令可以看到分支合並圖。

分支策略

master主分支應該非常穩定,用來發布新版本,一般情況下不允許在上面工作,工作一般情況下在新建的dev分支上工作,工作完后,比如上要發布,或者說dev分支代碼穩定后可以合並到主分支master上來。

4.4.5、刪除分支

刪除本地分支可以使用命令:$ git branch -d [branch-name],-D(大寫)強制刪除

刪除遠程分支可以使用如下指令:

$ git push origin --delete [branch-name]
$ git branch
-dr [remote/branch]

-d表示刪除分支。分支必須完全合並在其上游分支,或者在HEAD上沒有設置上游

-r表示遠程的意思remotes,如果-dr則表示刪除遠程分支

4.5、Git GUI 操作

通過命令行可以深刻的理解Git,Git GUI或IDE插件卻可以更加直觀操作Git,常用的Git GUI有如下這些:

4.5.1、GitHub for Desktop

全球開發人員交友俱樂部提供的強大工具,功能完善,使用方便。對於使用GitHub的開發人員來說是非常便捷的工具。

GitHub for Desktop不帶三方合並工具,你必須自己手動解決沖突才可以。

– 免費
– 同時支持 Windows 和 Mac:對於需要經常在不同的操作系統間切換的開發人員來說非常方便。
– 漂亮的界面:作為每天盯着看的工具,顏值是非常重要的
– 支持Pull Request:直接從客戶端提交PR,很方便
– Timeline 支持:直接在時間線上顯示每次提交的時間點和大小
– 支持git LFS:存儲大文件更加節省空間和高效
– 不支持三方合並:需要借助第三方工具才行

4.5.2、Source Tree

SourceTree是老牌的Git GUI管理工具了,也號稱是最好用的Git GUI工具。強大,功能豐富,基本操作和高級操作都設計得非常流暢,適合初學者上手,支持Git Flow。

– 免費
– 功能強大:無論你是新手還是重度用戶,SourceTree 都會讓你覺得很順手。對於非常重度用戶,Source Tree還支持自定義腳本的執行。
– 同時支持 Windows 和 Mac 操作系統
– 同時支持 Git 和 Mercurial 兩種 VCS
– 內置GitHub, BitBucket 和 Stash 的支持:直接綁定帳號即可操作遠程repo

4.5.3、TortoiseGit

小烏龜,SVN的超廣泛使用也使得這個超好用的Svn客戶端成了幾乎每個開發人員的桌面必備軟件。小烏龜只提供Windows版本,提供中文版支持的。

– 免費
– 只支持Windows操作系統:與文件管理器的良好集成
– 中文界面
– 與TortoiseSVN一脈相承的操作體驗

4.5.4、Git集成Gui工具

安裝Git時會集成安裝Gui工具,在Git菜單下可以找到,特點是:免費、簡單、不需要額外安裝

4.6、IDE集成的Git客戶端

對於使用IDE進行開發的程序員來說,可以不離開常用的IDE就直接操作源代碼管理系統是最好的選擇,以下是我對幾個常見的IDE集成的git客戶端:

4.6.1、Eclipse – Egit

作為Java集成開發環境的代表,Eclipse內置了egit這個插件來提供git的集成支持。實話實說,這個插件的功能非常豐富,無論是普通的clone, commit, pull/push操作;還是復雜一些的git flow都有支持。

4.6.2、Visual Studio – Git Integration & GitHub Extension

VS里面的Git支持已經相當的完善。直接克隆github上的repo

 

4.6.3、IntelliJ IDEA

4.7、幫助與代碼統計

1)、幫助文檔

完整的安裝了Git后有一個官方幫助,這是最權威的資料,方法如下:

比如我們要查看git commit的使用

執行時會打開對應的git幫助文檔,其實就在本地,當然您也可以去官網在線搜索,地址是: https://git-scm.com/docs

2)、信息查看與統計命令

#統計某人的代碼提交量,包括增加,刪除:
git log --author="$(git config --get user.name)" --pretty=tformat: --numstat | gawk '{ add += $1 ; subs += $2 ; loc += $1 - $2 } END { printf 
"added lines: %s removed lines : %s total lines: %s\n",add,subs,loc }' -

#倉庫提交者排名前 5(如果看全部,去掉 head 管道即可):
git log --pretty='%aN' | sort | uniq -c | sort -k1 -n -r | head -n 5

#倉庫提交者(郵箱)排名前 5:這個統計可能不會太准,因為很多人有不同的郵箱,但會使用相同的名字
git log --pretty=format:%ae | gawk -- '{ ++c[$0]; } END { for(cc in c) printf "%5d %s\n",c[cc],cc; }' | sort -u -n -r | head -n 5 

#貢獻者統計:
git log --pretty='%aN' | sort -u | wc -l

#提交數統計:
git log --oneline | wc -l 

# 顯示有變更的文件
$ git status

# 顯示當前分支的版本歷史
$ git log

# 顯示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

# 顯示所有提交過的用戶,按提交次數排序
$ git shortlog -sn

# 顯示指定文件是什么人在什么時間修改過
$ git blame [file]

# 顯示暫存區和工作區的差異
$ git diff

# 顯示暫存區和上一個commit的差異
$ git diff --cached [file]

# 顯示工作區與當前分支最新commit之間的差異
$ git diff HEAD

# 顯示兩次提交之間的差異
$ git diff [first-branch]...[second-branch]

# 顯示今天你寫了多少行代碼
$ git diff --shortstat "@{0 day ago}"

# 顯示某次提交的元數據和內容變化
$ git show [commit]

# 顯示某次提交發生變化的文件
$ git show --name-only [commit]

# 顯示某次提交時,某個文件的內容
$ git show [commit]:[filename]

# 顯示當前分支的最近幾次提交
$ git reflog

示例:

五、遠程倉庫

Git是分布式版本控制系統,同一個Git倉庫,可以分布到不同的機器上,但開發參與者必須在同一個網絡中,且必須有一個項目的原始版本,通常的辦法是讓一台電腦充當服務器的角色,每天24小時開機,其他每個人都從這個“服務器”倉庫克隆一份到自己的電腦上,並且各自把各自的提交推送到服務器倉庫里,也從服務器倉庫中拉取別人的提交。完全可以自己搭建一台運行Git的服務器但現在更適合的做法是使用免費的托管平台。

同時相較於傳統的代碼都是管理到本機或者內網。 一旦本機或者內網機器出問題,代碼可能會丟失,使用遠端代碼倉庫將永遠存在一個備份。同時也免去了搭建本地代碼版本控制服務的繁瑣。 雲計算時代 Git 以其強大的分支和克隆功能,更加方便了開發者遠程協作。

5.1、托管平台

Git代碼托管平台,首先推薦的是GitHub,好多好的開源項目都來自GitHub,但是GitHub只能新建公開的Git倉庫,私有倉庫要收費,有時候訪問比較卡,如果你做的是一個開源項目,可以首選GitHub。下面推薦幾個比較好的Git代碼托管平台:

5.1.1、GitHub

關於GItHub相信大家都有耳聞,我就不詳細介紹了。GitHub地址: https://github.com/,其首頁如圖:

5.1.2、Gitlab

對於有些人,提到GitHub就會自然的想到Gitlab,Gitlab支持無限的公有項目和私有項目。Gitlab地址: https://about.gitlab.com/,其首頁截圖如圖:

5.1.3、Bitbucket

bitbucket免費支持5個開發成員的團隊創建無限私有代碼托管庫。bitbucket地址:

5.1.4、開源中國代碼托管

開源中國一個賬號最多可以創建1000個項目,包含公有和私有,開源中國代碼托管地址: http://git.oschina.net/,其首頁如圖:

5.1.5、(推薦)coding.net

談到coding.net,首先必須提的是速度快,功能與開源中國相似,同樣一個賬號最多可以創建1000個項目(5個私有),也支持任務的創建等。coding.net地址: https://coding.net/

我個人比較推薦Coding.net、GItHub。

當然還有許多,如CSDN,百度,阿里等,歡迎大家比較后推薦。

選擇國外的主機請考慮網速,選擇國內的主機請考慮穩定與安全性。

5.2、申請帳號與設置

因為coding.net免費,可以創建私有項目,且速度不錯,這里我們以coding.net為托管平台完成遠程倉庫的帳號申請與操作。

5.2.1、申請帳號

1)、打開 https://coding.net/,點擊右上角的注冊按鈕:

 2)、填寫好注冊信息通過郵箱或手機驗證后注冊就成功了。登錄到個人首頁。

如果是QQ郵箱請注意激活郵件可能會被當着垃圾郵件,到垃圾箱中可以找到。

5.2.2、創建項目

登錄成功后,點擊左側菜單項目,點擊加號新建項目,這里創建的是一個公開項目,沒有Readme.md、許可證與忽視文件,原因是如果你本地已經有一個項目了,想提交到遠程倉庫而新創建的3個文件本地沒有,當然有辦法但初學避免麻煩這里我就不添加這三個文件了,輸入相關信息后點擊創建就成功了。

5.2.3、提交源代碼到遠程倉庫

從上圖可以看出創建地址有兩種:

https 類型的:https://git.coding.net/zhangguoGit/project7.git

SSH類型的:git@git.coding.net:zhangguoGit/project7.git

HTTPS(推薦輕量級用戶使用)

使用加密的網頁訪問通道讀寫倉庫,使用用戶名及密碼進行鑒權。 避免重復輸入密碼,查看 怎樣在每次 Push 時不用重復輸入密碼

提示:Git 用戶名為 Coding 的賬戶郵箱或者個性后綴,密碼為 Coding 的賬戶密碼。
注意:HTTPS 方式 push 大文件可能引發錯誤,查看  Push 出錯怎么辦

SSH(推薦資深用戶或經常推送大型文件用戶使用)

SSH全稱(Secure SHell)是一種網絡協議,顧名思義就是非常安全的shell,主要用於計算機間加密傳輸。
使用加密通道讀寫倉庫,無單次上傳限制,需先設置 “賬戶 SSH 公鑰”,完成配對驗證。

導入倉庫可以將已存在的Git項目或SVN項目直接導入。

在命令行創建項目:

#1、創建目錄
mkdir project7

#2、進入目錄
cd project7

#3、初始化目錄為git項目
git init

#4、創建md文件追加內容# project7(一級標題)
echo "# project7" >> README.md

#5、添加說明文件到暫存區
git add README.md

#6、提交到本地倉庫並寫日志
git commit -m "first commit"

#7、添加遠程主機,主機名為origin 地址為https://git.coding.net/zhangguoGit/project7.git
git remote add origin https://git.coding.net/zhangguoGit/project7.git

#8、本地的master分支推送到origin主機,同時指定origin為默認主機,后面就可以不加任何參數使用git push了,-u 參數指定一個默認主機
git push -u origin master

如果創建已經創建則只需要第7步與第8步就好了。

5.2.4、Markdown文件(.md文件)

Markdown 是一種輕量級標記語言,它允許人們“使用易讀易寫的純文本格式編寫文檔,然后轉換成有效的XHTML(或者HTML)文檔。

Markdown 語法的目標是:成為一種適用於網絡的書寫語言。

1.標題

# 一級標題
## 二級標題
### 三級標題
#### 四級標題
##### 五級標題
###### 六級標題

####### 七級標題

效果:

2.列表

分為有序列表和無序列表。

有序列表

1. 1
2. 2
3. 3

無序列表

* 1
* 2
* 3

3.引用

> 這是引用

4.圖片和鏈接

兩者格式區別在於“ ! ”。

![圖片描述](圖片鏈接)

[鏈接描述](鏈接地址)

5.粗體和斜體

**這是粗體**

*這是斜體*

6.表格

| Tables | Are | Cool |
| ------------ |:------------:| -----:|
| col 3 is | right-aligned| $1600 |
| col 2 is | centered | $12 |
| zebra stripes| are neat | &1 |

7.代碼框

用``這個把代碼包裹起來

8.分割線

輸入***即可。

示例:

大標題      
===================================    
  大標題一般顯示工程名,類似html的\<h1\><br />     
  你只要在標題下面跟上=====即可     
    
       
中標題     
-----------------------------------     
  中標題一般顯示重點項,類似html的\<h2\><br />     
  你只要在標題下面輸入------即可     
#       
### 小標題     
  小標題類似html的\<h3\><br />     
  小標題的格式如下 ### 小標題<br />     
  注意#和標題字符中間要有空格     
    
### 注意!!!下面所有語法的提示我都先用小標題提醒了!!!      
    
### 單行文本框     
    這是一個單行的文本框,只要兩個Tab再輸入文字即可     
             
### 多行文本框       
    這是一個有多行的文本框     
    你可以寫入代碼等,每行文字只要輸入兩個Tab再輸入文字即可     
    這里你可以輸入一段代碼     
    
### 比如我們可以在多行文本框里輸入一段代碼,來一個Java版本的HelloWorld吧     
public class HelloWorld {     
    
/**     
* @param args     
*/     
public static void main(String[] args) {     
   ```System.out.println("HelloWorld!"); ```     
   }     
}    
### 鏈接     
1.[點擊這里你可以鏈接到www.baidu.com](http://www.baidu.com)<br />     
2.[點擊這里我你可以鏈接到我的博客](<a target=_blank href="http://www.cnblogs.com/best">http://www.cnblogs.com/best</a>)<br />     
    
###只是顯示圖片     
![github](https://pic.cnblogs.com/avatar/63651/20170217085118.png"github") 
    
### 文字被些字符包圍     
> 文字被些字符包圍     
>     
> 只要再文字前面加上>空格即可     
>     
> 如果你要換行的話,新起一行,輸入>空格即可,后面不接文字     
> 但> 只能放在行首才有效     
    
### 文字被些字符包圍,多重包圍     
> 文字被些字符包圍開始     
>     
> > 只要再文字前面加上>空格即可     
>     
>  > > 如果你要換行的話,新起一行,輸入>空格即可,后面不接文字     
>     
> > > > 但> 只能放在行首才有效     
    
### 特殊字符處理     
有一些特殊字符如<,#等,只要在特殊字符前面加上轉義字符\即可<br />     
你想換行的話其實可以直接用html標簽\<br /\>    
View Code

對應的HTML:

<h1>大標題      </h1>

<p>大標題一般顯示工程名,類似html的\<h1\><br /> <br>
  你只要在標題下面跟上=====即可     </p>

<h2>中標題     </h2>

<p>中標題一般顯示重點項,類似html的\<h2\><br /> <br>
  你只要在標題下面輸入------即可     </p>

<h1> </h1>

<h3>小標題</h3>

<p>小標題類似html的\<h3\><br /> <br>
  小標題的格式如下 ### 小標題<br /> <br>
  注意#和標題字符中間要有空格     </p>

<h3>注意!!!下面所有語法的提示我都先用小標題提醒了!!!</h3>

<h3>單行文本框</h3>

<pre><code>這是一個單行的文本框,只要兩個Tab再輸入文字即可     
</code></pre>

<h3>多行文本框</h3>

<pre><code>這是一個有多行的文本框     
你可以寫入代碼等,每行文字只要輸入兩個Tab再輸入文字即可     
這里你可以輸入一段代碼     
</code></pre>

<h3>比如我們可以在多行文本框里輸入一段代碼,來一個Java版本的HelloWorld吧</h3>

<p>public class HelloWorld {     </p>

<p>/** <br>
* @param args <br>
*/ <br>
public static void main(String[] args) { <br>
   <code>System.out.println("HelloWorld!");</code> <br>
   } <br>
}    </p>

<h3>鏈接</h3>

<p>1.<a href="http://www.baidu.com">點擊這里你可以鏈接到www.baidu.com</a><br /> <br>
2.[點擊這里我你可以鏈接到我的博客](<a target=_blank href="http://www.cnblogs.com/best">http://www.cnblogs.com/best</a>)<br />     </p>

<h3>只是顯示圖片</h3>

<p><img src="https://pic.cnblogs.com/avatar/63651/20170217085118.png" alt="github" title="github" /> </p>

<h3>文字被些字符包圍</h3>

<blockquote>
  <p>文字被些字符包圍     </p>
  
  <p>只要再文字前面加上>空格即可     </p>
  
  <p>如果你要換行的話,新起一行,輸入>空格即可,后面不接文字 <br>
  但> 只能放在行首才有效     </p>
</blockquote>

<h3>文字被些字符包圍,多重包圍</h3>

<blockquote>
  <p>文字被些字符包圍開始     </p>
  
  <blockquote>
    <p>只要再文字前面加上>空格即可     </p>
    
    <blockquote>
      <p>如果你要換行的話,新起一行,輸入>空格即可,后面不接文字     </p>
      
      <blockquote>
        <p>但> 只能放在行首才有效     </p>
      </blockquote>
    </blockquote>
  </blockquote>
</blockquote>

<h3>特殊字符處理</h3>

<p>有一些特殊字符如&lt;,#等,只要在特殊字符前面加上轉義字符\即可<br /> <br>
你想換行的話其實可以直接用html標簽\<br /\>    </p>
View Code

結果:

在線實時預覽工具

5.3、遠程倉庫操作

申請到了Git遠程倉庫的帳號並創建了一個空的遠程倉庫現在我們就可以結合本地的倉庫與遠程倉庫一起協同工作了,模擬多人協同開發,這里我們全部使用命令完成。

5.3.1、常用操作指令

# 下載遠程倉庫的所有變動
$ git fetch [remote]

# 顯示所有遠程倉庫
$ git remote -v

# 顯示某個遠程倉庫的信息
$ git remote show [remote]

# 增加一個新的遠程倉庫,並命名
$ git remote add [shortname] [url]

# 取回遠程倉庫的變化,並與本地分支合並
$ git pull [remote] [branch]

# 上傳本地指定分支到遠程倉庫
$ git push [remote] [branch]

# 強行推送當前分支到遠程倉庫,即使有沖突
$ git push [remote] --force

# 推送所有分支到遠程倉庫
$ git push [remote] --all

#簡單查看遠程---所有倉庫
git remote  (只能查看遠程倉庫的名字)
#查看單個倉庫 git remote show [remote-branch-name] #新建遠程倉庫 git remote add [branchname] [url] #修改遠程倉庫 git remote rename [oldname] [newname] #刪除遠程倉庫 git remote rm [remote-name] #獲取遠程倉庫數據 git fetch [remote-name] (獲取倉庫所有更新,但不自動合並當前分支) git pull (獲取倉庫所有更新,並自動合並到當前分支) #上傳數據,如git push origin master git push [remote-name] [branch]

5.3.2、git clone 克隆

遠程操作的第一步,通常是從遠程主機克隆一個版本庫,這時就要用到git clone命令。

$ git clone <版本庫的網址>

比如,克隆一個上課示例的版本庫。

$ git clone https://github.com/zhangguo5/AngularJS04_BookStore.git

該命令會在本地主機生成一個目錄,與遠程主機的版本庫同名。如果要指定不同的目錄名,可以將目錄名作為git clone命令的第二個參數。

$ git clone <版本庫的網址> <本地目錄名>

git clone支持多種協議,除了HTTP(s)以外,還支持SSH、Git、本地文件協議等,下面是一些例子。

$ git clone http[s]://example.com/path/to/repo.git/
$ git clone ssh://example.com/path/to/repo.git/
$ git clone git://example.com/path/to/repo.git/
$ git clone /opt/git/project.git 
$ git clone file:///opt/git/project.git
$ git clone ftp[s]://example.com/path/to/repo.git/
$ git clone rsync://example.com/path/to/repo.git/

SSH協議還有另一種寫法。

$ git clone [user@]example.com:path/to/repo.git/

通常來說,Git協議下載速度最快,SSH協議用於需要用戶認證的場合。各種協議優劣的詳細討論請參考 官方文檔

示例:

結果:

5.3.3、git remote

為了便於管理,Git要求每個遠程主機都必須指定一個主機名。git remote命令就用於管理主機名。

不帶選項的時候,git remote命令列出所有遠程主機。

$ git remote

 

使用-v選項,可以參看遠程主機的網址。

$ git remote -v

 

上面命令表示,當前只有一台遠程主機,叫做origin,以及它的網址。

克隆版本庫的時候,所使用的遠程主機自動被Git命名為origin。如果想用其他的主機名,需要用git clone命令的-o選項指定。

$ git clone -o WeUI https://github.com/Tencent/weui.git
$ git remote

 

上面命令表示,克隆的時候,指定遠程主機叫做WeUI。

git remote show命令加上主機名,可以查看該主機的詳細信息。

$ git remote show <主機名>

 

git remote add命令用於添加遠程主機。

$ git remote add <主機名> <網址>

 

git remote rm命令用於刪除遠程主機。

$ git remote rm <主機名>

 

git remote rename命令用於遠程主機的改名。

$ git remote rename <原主機名> <新主機名>

 

5.3.4、git fetch

一旦遠程主機的版本庫有了更新(Git術語叫做commit),需要將這些更新取回本地,這時就要用到git fetch命令。

$ git fetch <遠程主機名>

 

上面命令將某個遠程主機的更新,全部取回本地。

git fetch命令通常用來查看其他人的進程,因為它取回的代碼對你本地的開發代碼沒有影響。

默認情況下,git fetch取回所有分支(branch)的更新。如果只想取回特定分支的更新,可以指定分支名。

$ git fetch <遠程主機名> <分支名>

 

比如,取回origin主機的master分支。

$ git fetch origin master

所取回的更新,在本地主機上要用"遠程主機名/分支名"的形式讀取。比如origin主機的master,就要用origin/master讀取。

git branch命令的-r選項,可以用來查看遠程分支,-a選項查看所有分支。

$ git branch -r
origin/master

$ git branch -a
* master
  remotes/origin/master

上面命令表示,本地主機的當前分支是master,遠程分支是origin/master

取回遠程主機的更新以后,可以在它的基礎上,使用git checkout命令創建一個新的分支。

$ git checkout -b newBrach origin/master

上面命令表示,在origin/master的基礎上,創建一個新分支。

此外,也可以使用git merge命令或者git rebase命令,在本地分支上合並遠程分支。

$ git merge origin/master
# 或者
$ git rebase origin/master

上面命令表示在當前分支上,合並origin/master

5.3.5、git pull

git pull命令的作用是,取回遠程主機某個分支的更新,再與本地的指定分支合並。它的完整格式稍稍有點復雜。

$ git pull <遠程主機名> <遠程分支名>:<本地分支名>

比如,取回origin主機的next分支,與本地的master分支合並,需要寫成下面這樣。

$ git pull origin next:master

如果遠程分支是與當前分支合並,則冒號后面的部分可以省略。

$ git pull origin next

上面命令表示,取回origin/next分支,再與當前分支合並。實質上,這等同於先做git fetch,再做git merge

$ git fetch origin
$ git merge origin/next

在某些場合,Git會自動在本地分支與遠程分支之間,建立一種追蹤關系(tracking)。比如,在git clone的時候,所有本地分支默認與遠程主機的同名分支,建立追蹤關系,也就是說,本地的master分支自動"追蹤"origin/master分支。

Git也允許手動建立追蹤關系。

git branch --set-upstream master origin/next

上面命令指定master分支追蹤origin/next分支。

如果當前分支與遠程分支存在追蹤關系,git pull就可以省略遠程分支名。

$ git pull origin

上面命令表示,本地的當前分支自動與對應的origin主機"追蹤分支"(remote-tracking branch)進行合並。

如果當前分支只有一個追蹤分支,連遠程主機名都可以省略。

$ git pull

上面命令表示,當前分支自動與唯一一個追蹤分支進行合並。

如果合並需要采用rebase模式,可以使用--rebase選項。

$ git pull --rebase <遠程主機名> <遠程分支名>:<本地分支名>

如果遠程主機刪除了某個分支,默認情況下,git pull 不會在拉取遠程分支的時候,刪除對應的本地分支。這是為了防止,由於其他人操作了遠程主機,導致git pull不知不覺刪除了本地分支。

但是,你可以改變這個行為,加上參數 -p 就會在本地刪除遠程已經刪除的分支。

$ git pull -p
# 等同於下面的命令
$ git fetch --prune origin 
$ git fetch -p

5.3.6、git push

git push命令用於將本地分支的更新,推送到遠程主機。它的格式與git pull命令相仿。

$ git push <遠程主機名> <本地分支名>:<遠程分支名>

注意,分支推送順序的寫法是<來源地>:<目的地>,所以git pull是<遠程分支>:<本地分支>,而git push是<本地分支>:<遠程分支>。

如果省略遠程分支名,則表示將本地分支推送與之存在"追蹤關系"的遠程分支(通常兩者同名),如果該遠程分支不存在,則會被新建。

$ git push origin master

 

上面命令表示,將本地的master分支推送到origin主機的master分支。如果后者不存在,則會被新建。

如果省略本地分支名,則表示刪除指定的遠程分支,因為這等同於推送一個空的本地分支到遠程分支。

$ git push origin :master
# 等同於
$ git push origin --delete master

 

上面命令表示刪除origin主機的master分支。

如果當前分支與遠程分支之間存在追蹤關系,則本地分支和遠程分支都可以省略。

$ git push origin

上面命令表示,將當前分支推送到origin主機的對應分支。

如果是新建分支第一次push,會提示:
  fatal: The current branch dev1 has no upstream branch.
  To push the current branch and set the remote as upstream, use
  git push --set-upstream origin dev1
  輸入這行命令,然后輸入用戶名和密碼,就push成功了。

  以后的push就只需要輸入git push origin

原因是:

#因為在git的全局配置中,有一個push.default屬性,其決定了git push操作的默認行為。在Git 2.0之前,這個屬性的默認被設為'matching',2.0之后則被更改為了'simple'。

#我們可以通過git version確定當前的git版本(如果小於2.0,更新是個更好的選擇),通過git config --global push.default 'option'改變push.default的默認行為(或者也可直接編輯~/.gitconfig文件)。

push.default 有以下幾個可選值:
nothing, current, upstream, simple, matching

其用途分別為:
nothing - push操作無效,除非顯式指定遠程分支,例如git push origin develop(我覺得。。。可以給那些不願學git的同事配上此項)。
current - push當前分支到遠程同名分支,如果遠程同名分支不存在則自動創建同名分支。
upstream - push當前分支到它的upstream分支上(這一項其實用於經常從本地分支push/pull到同一遠程倉庫的情景,這種模式叫做central workflow)。
simple - simple和upstream是相似的,只有一點不同,simple必須保證本地分支和它的遠程
upstream分支同名,否則會拒絕push操作。
matching - push所有本地和遠程兩端都存在的同名分支。
因此如果我們使用了git2
.0之前的版本,push.default = matching,git push后則會推送當前分支代碼到遠程分支,而2.0之后,push.default = simple,如果沒有指定當前分支的upstream分支,就會收到上文的fatal提示。

如果當前分支只有一個追蹤分支,那么主機名都可以省略。

$ git push

如果當前分支與多個主機存在追蹤關系,則可以使用-u選項指定一個默認主機,這樣后面就可以不加任何參數使用git push

$ git push -u origin master

上面命令將本地的master分支推送到origin主機,同時指定origin為默認主機,后面就可以不加任何參數使用git push了。

不帶任何參數的git push,默認只推送當前分支,這叫做simple方式。此外,還有一種matching方式,會推送所有有對應的遠程分支的本地分支。Git 2.0版本之前,默認采用matching方法,現在改為默認采用simple方式。如果要修改這個設置,可以采用git config命令。

$ git config --global push.default matching
# 或者
$ git config --global push.default simple

還有一種情況,就是不管是否存在對應的遠程分支,將本地的所有分支都推送到遠程主機,這時需要使用--all選項。

$ git push --all origin

上面命令表示,將所有本地分支都推送到origin主機。

如果遠程主機的版本比本地版本更新,推送時Git會報錯,要求先在本地做git pull合並差異,然后再推送到遠程主機。這時,如果你一定要推送,可以使用--force選項。

$ git push --force origin 

上面命令使用--force選項,結果導致遠程主機上更新的版本被覆蓋。除非你很確定要這樣做,否則應該盡量避免使用--force選項。

最后,git push不會推送標簽(tag),除非使用--tags選項。

$ git push origin --tags

5.4、在命令行中同步本地倉庫示例

假定我們創建好了一個遠程倉庫地址為:https://coding.net/u/zhangguo5/p/project7/git,現在我們在本地創建一個項目並同步到遠程倉庫中。

1)、創建文件添加到暫存區

2)、提交到本地倉庫

3)、提交到遠程倉庫

添加遠程主機地址:

推送文件:

結果:

說明:這里我使用的是SSH方式提交的,所有並沒有讓我輸入用戶名與密碼,如果你使用https方式提交則要配置用戶名與郵箱,還要輸入密碼。

5.5、IDEA中Git的使用

工作中多人使用版本控制軟件協作開發,常見的應用場景歸納如下:

假設小組中有兩個人,組長蓋茨,組員艾倫

場景一:蓋茨創建項目並提交到遠程Git倉庫

場景二:艾倫從遠程Git倉庫上獲取項目源碼

場景三:艾倫修改了部分源碼,提交到遠程倉庫

場景四:蓋茨從遠程倉庫獲取艾倫的提交

場景五:艾倫接受了一個新功能的任務,創建了一個分支並在分支上開發

場景六:艾倫把分支提交到遠程Git倉庫

場景七:蓋茨獲取艾倫提交的分支

場景八:蓋茨把分支合並到主干

下面來看以上各場景在IDEA中對應的操作。

場景一:蓋茨創建項目並提交到遠程Git倉庫

在IDEA中配置Git

測試環境是否正常

創建好項目,這里創建了一個Maven項目,結構如下,當然可以是任意項目:

選擇VCS - > Enable Version Control Integration,允許將項目集成到版本控制器中

選擇版本控制器類型

完成后當前項目就變成一個Git項目,是工作空間

點擊OK后創建完成本地倉庫,注意,這里僅僅是本地的。下面把項目源碼添加到本地倉庫。

下圖是Git與提交有關的三個命令對應的操作,Add命令是把文件從IDE的工作目錄添加到本地倉庫的stage區,Commit命令把stage區的暫存文件提交到當前分支的倉庫,並清空stage區。Push命令把本地倉庫的提交同步到遠程倉庫。

IDEA中對操作做了一定的簡化,Commit和Push可以在一步中完成。

具體操作,在項目上點擊右鍵,選擇Git菜單,如果使用Add則將文件從工作空間提交到暫存庫,Commit Directory則是同時完成提交到暫存與本地倉庫。

 選擇要提交的文件,填寫消息

將本地倉庫的內容提交到遠程倉庫

 定義遠程地址的別名

 

 輸入名稱與URL

 點擊push將本地倉庫的內容推送到遠程服務器

 

 提示Push Successful就成功了

 提交后的遠程庫

 

場景二:艾倫從遠程Git倉庫上獲取項目源碼

即克隆項目,操作如下:

輸入蓋茨Push時填寫的遠程倉庫地址

填寫倉庫地址、要克隆到的父目錄與項目目錄

接下來按向導操作,即可把項目從遠程倉艾倫隆到本地倉庫和IDE工作區。

當提示簽出成功點擊打開就可以看到項目了

下載到本地的文件

其它方法

場景三:艾倫修改了部分源碼,提交到遠程倉庫

這個操作和首次提交的流程基本一致,分別是 Add -> Commit -> Push。請參考場景一

 添加一個類,並提交

 

提交到本地倉庫

提交到遠程倉庫

場景四:蓋茨從遠程倉庫獲取艾倫的提交

獲取更新有兩個命令:Fetch和Pull,Fetch是從遠程倉庫下載文件到本地的origin/master,然后可以手動對比修改決定是否合並到本地的master庫。Pull則是直接下載並合並。如果各成員在工作中都執行修改前先更新的規范,則可以直接使用Pull方式以簡化操作。

選擇分支

場景五:艾倫接受了一個新功能的任務,創建了一個分支並在分支上開發

建分支也是一個常用的操作,例如臨時修改bug、開發不確定是否加入的功能等,都可以創建一個分支,再等待合適的時機合並到主干。

創建流程如下:

選擇New Branch並輸入一個分支的名稱

創建完成后注意IDEA的右下角,如下圖,Git: dev表示已經自動切換到dev分支,當前工作在這個分支上。

點擊后彈出一個小窗口,在Local Branches中有其他可用的本地分支選項,點擊后選擇Checkout即可切換當前工作的分支(見場景7操作切換其他分支)。

如下圖,點擊Checkout

注意,這里創建的分支僅僅在本地倉庫,如果想讓組長蓋茨獲取到這個分支,還需要提交到遠程倉庫。

場景六:艾倫把分支提交到遠程Git倉庫

切換到新建的分支,使用Push功能

提交到遠程

艾倫將新開發的功能提交到遠程

提交到遠程

場景七:蓋茨獲取艾倫提交的分支

使用Pull功能打開更新窗口,點擊Remote欄后面的刷新按鈕,會在Branches to merge欄中刷新出新的分支。這里並不想做合並,所以不要選中任何分支,直接點擊Pull按鈕完成操作。

 

更新后,再點擊右下角,可以看到在Remote Branches區已經有了新的分支,點擊后在彈出的子菜單中選擇Checkout as new local branch,在本地倉庫中創建該分支。完成后在Local Branches區也會出現該分支的選項,可以按上面的方法,點擊后選擇Checkout切換。

切換遠程分支:

切換本地分支:

場景八:蓋茨把分支合並到主干

新功能開發完成,體驗很好,項目組決定把該功能合並到主干上。

切換到master分支,選擇Merge Changes

選擇要合並的分支,點擊Merge完成

六、作業與評分標准

作業要求:

1、申請一個遠程git帳號,創建一個倉庫

2、將本人第一次提升時提交的IDEA作業升級為一個git項目並提交到遠程倉庫中

3、在git bash下執行: history > mylog.txt,並提交到遠程倉庫 (把本地執行過的git指令導出到mylog.txt文件中)

提交內容:

將您同步的遠程倉庫地址,如:https://coding.net/u/yourname/p/ideaproject/git 

發送到我的郵箱99510309#qq.com或在當前博客下留言

提交時間:

2017-09-28 星期四 中午12:00前

七、資源與資料下載

資料鏈接: https://pan.baidu.com/s/1c20DVOW  密碼: p9ri

Git教程下載_王亮(大神)

 

示例1:

Administrator@PC201501031108 MINGW64 ~
$ cd e:

Administrator@PC201501031108 MINGW64 /e
$ mkdir gitDemo

Administrator@PC201501031108 MINGW64 /e
$ cd gitDemo

Administrator@PC201501031108 MINGW64 /e/gitDemo
$ git init #初始化倉庫
Initialized empty Git repository in E:/gitDemo/.git/

Administrator@PC201501031108 MINGW64 /e/gitDemo (master)
$ echo Hello
Hello

Administrator@PC201501031108 MINGW64 /e/gitDemo (master)
$ echo file1
file1

Administrator@PC201501031108 MINGW64 /e/gitDemo (master)
$ echo file1 >file1.txt

Administrator@PC201501031108 MINGW64 /e/gitDemo (master)
$ cat file1.txt
file1

Administrator@PC201501031108 MINGW64 /e/gitDemo (master)
$ git status
On branch master

Initial commit

Untracked files:
  (use "git add <file>..." to include in what will be committed

        file1.txt

nothing added to commit but untracked files present (use "git a

Administrator@PC201501031108 MINGW64 /e/gitDemo (master)
$ git add .
warning: LF will be replaced by CRLF in file1.txt.
The file will have its original line endings in your working directory.

Administrator@PC201501031108 MINGW64 /e/gitDemo (master)
$ git status
On branch master

Initial commit

Changes to be committed:
  (use "git rm --cached <file>..." to unstage)

        new file:   file1.txt


Administrator@PC201501031108 MINGW64 /e/gitDemo (master)
$ git commit -m 提交文件file1.txt
[master (root-commit) 3f95f8b] 提交文件file1.txt
 1 file changed, 1 insertion(+)
 create mode 100644 file1.txt

Administrator@PC201501031108 MINGW64 /e/gitDemo (master)
$ git status
On branch master
nothing to commit, working tree clean

Administrator@PC201501031108 MINGW64 /e/gitDemo (master)
$
View Code

示例2:

On branch master

Initial commit

Changes to be committed:
  (use "git rm --cached <file>..." to unstage)

        new file:   file1.txt


Administrator@PC201501031108 MINGW64 /e/gitDemo (master)
$ git commit -m 提交文件file1.txt
[master (root-commit) 3f95f8b] 提交文件file1.txt
 1 file changed, 1 insertion(+)
 create mode 100644 file1.txt

Administrator@PC201501031108 MINGW64 /e/gitDemo (master)
$ git status
On branch master
nothing to commit, working tree clean

Administrator@PC201501031108 MINGW64 /e/gitDemo (master)
$ clear

Administrator@PC201501031108 MINGW64 /e/gitDemo (master)
$ cat file1.txt
file1

Administrator@PC201501031108 MINGW64 /e/gitDemo (master)
$ echo file1_1 >> file1.txt

Administrator@PC201501031108 MINGW64 /e/gitDemo (master)
$ cat file1.txt
file1
file1_1

Administrator@PC201501031108 MINGW64 /e/gitDemo (master)
$ git status
On branch master
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

        modified:   file1.txt

no changes added to commit (use "git add" and/or "git commit -a")

Administrator@PC201501031108 MINGW64 /e/gitDemo (master)
$ git add file1.txt
warning: LF will be replaced by CRLF in file1.txt.
The file will have its original line endings in your working directory.

Administrator@PC201501031108 MINGW64 /e/gitDemo (master)
$ git status
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

        modified:   file1.txt


Administrator@PC201501031108 MINGW64 /e/gitDemo (master)
$ git commit -m 修改了file1.txt
[master 69ac343] 修改了file1.txt
 1 file changed, 1 insertion(+)

Administrator@PC201501031108 MINGW64 /e/gitDemo (master)
$ git status
On branch master
nothing to commit, working tree clean

Administrator@PC201501031108 MINGW64 /e/gitDemo (master)
$ echo file1_2 >> file1.txt

Administrator@PC201501031108 MINGW64 /e/gitDemo (master)
$ cat file1.txt
file1
file1_1
file1_2

Administrator@PC201501031108 MINGW64 /e/gitDemo (master)
$ git status
On branch master
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

        modified:   file1.txt

no changes added to commit (use "git add" and/or "git commit -a")

Administrator@PC201501031108 MINGW64 /e/gitDemo (master)
$ git checkout -- file1.txt

Administrator@PC201501031108 MINGW64 /e/gitDemo (master)
$ git status
On branch master
nothing to commit, working tree clean

Administrator@PC201501031108 MINGW64 /e/gitDemo (master)
$ cat file1.txt
file1
file1_1

Administrator@PC201501031108 MINGW64 /e/gitDemo (master)
$ rm file1.txt

Administrator@PC201501031108 MINGW64 /e/gitDemo (master)
$ ll
total 0

Administrator@PC201501031108 MINGW64 /e/gitDemo (master)
$ ll
total 0

Administrator@PC201501031108 MINGW64 /e/gitDemo (master)
$ git status
On branch master
Changes not staged for commit:
  (use "git add/rm <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

        deleted:    file1.txt

no changes added to commit (use "git add" and/or "git commit -a")

Administrator@PC201501031108 MINGW64 /e/gitDemo (master)
$ git add /rm
fatal: C:/Program Files/Git/rm: 'C:/Program Files/Git/rm' is outside repository

Administrator@PC201501031108 MINGW64 /e/gitDemo (master)
$ git add
Nothing specified, nothing added.
Maybe you wanted to say 'git add .'?

Administrator@PC201501031108 MINGW64 /e/gitDemo (master)
$ git add  .

Administrator@PC201501031108 MINGW64 /e/gitDemo (master)
$ git status
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

        deleted:    file1.txt


Administrator@PC201501031108 MINGW64 /e/gitDemo (master)
$ git commit -m 刪除文件file1.txt
[master f41e819] 刪除文件file1.txt
 1 file changed, 2 deletions(-)
 delete mode 100644 file1.txt

Administrator@PC201501031108 MINGW64 /e/gitDemo (master)
$ git status
On branch master
nothing to commit, working tree clean

Administrator@PC201501031108 MINGW64 /e/gitDemo (master)
$ git log
commit f41e819f45c8871908202f666e920a9326684c75
Author: zhangguoGit <2676656856@qq.com>
Date:   Fri Nov 10 15:17:57 2017 +0800

    刪除文件file1.txt

commit 69ac343c49795927291d9bb668ee26bc76ed0eb0
Author: zhangguoGit <2676656856@qq.com>
Date:   Fri Nov 10 15:14:22 2017 +0800

    修改了file1.txt

commit 3f95f8bc24b4dfd5bc6b44f50bdea686d05de993
Author: zhangguoGit <2676656856@qq.com>
Date:   Fri Nov 10 14:56:31 2017 +0800

    提交文件file1.txt

Administrator@PC201501031108 MINGW64 /e/gitDemo (master)
$ echo file2.txt > file2.txt

Administrator@PC201501031108 MINGW64 /e/gitDemo (master)
$ cat file2.txt
file2.txt

Administrator@PC201501031108 MINGW64 /e/gitDemo (master)
$ git add .
warning: LF will be replaced by CRLF in file2.txt.
The file will have its original line endings in your working directory.

Administrator@PC201501031108 MINGW64 /e/gitDemo (master)
$ git commit -m 添加了文件file2.txt
[master 4cc7d2a] 添加了文件file2.txt
 1 file changed, 1 insertion(+)
 create mode 100644 file2.txt

Administrator@PC201501031108 MINGW64 /e/gitDemo (master)
$ git status
On branch master
nothing to commit, working tree clean

Administrator@PC201501031108 MINGW64 /e/gitDemo (master)
$ rm file2.txt

Administrator@PC201501031108 MINGW64 /e/gitDemo (master)
$ git status
On branch master
Changes not staged for commit:
  (use "git add/rm <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

        deleted:    file2.txt

no changes added to commit (use "git add" and/or "git commit -a")

Administrator@PC201501031108 MINGW64 /e/gitDemo (master)
$ git checkout --file2.txt
error: unknown option `file2.txt'
usage: git checkout [<options>] <branch>
   or: git checkout [<options>] [<branch>] -- <file>...

    -q, --quiet           suppress progress reporting
    -b <branch>           create and checkout a new branch
    -B <branch>           create/reset and checkout a branch
    -l                    create reflog for new branch
    --detach              detach HEAD at named commit
    -t, --track           set upstream info for new branch
    --orphan <new-branch>
                          new unparented branch
    -2, --ours            checkout our version for unmerged files
    -3, --theirs          checkout their version for unmerged files
    -f, --force           force checkout (throw away local modifications)
    -m, --merge           perform a 3-way merge with the new branch
    --overwrite-ignore    update ignored files (default)
    --conflict <style>    conflict style (merge or diff3)
    -p, --patch           select hunks interactively
    --ignore-skip-worktree-bits
                          do not limit pathspecs to sparse entries only
    --ignore-other-worktrees
                          do not check if another worktree is holding the given ref
    --progress            force progress reporting


Administrator@PC201501031108 MINGW64 /e/gitDemo (master)
$ git checkout -- file2.txt

Administrator@PC201501031108 MINGW64 /e/gitDemo (master)
$ git status
On branch master
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

        modified:   file2.txt

no changes added to commit (use "git add" and/or "git commit -a")

Administrator@PC201501031108 MINGW64 /e/gitDemo (master)
$ git commit -m 修改了file2.txt
On branch master
Changes not staged for commit:
        modified:   file2.txt

no changes added to commit

Administrator@PC201501031108 MINGW64 /e/gitDemo (master)
$ git add .

Administrator@PC201501031108 MINGW64 /e/gitDemo (master)
$ git commit -m 修改了file2.txt
[master c7690b8] 修改了file2.txt
 1 file changed, 11 insertions(+)

Administrator@PC201501031108 MINGW64 /e/gitDemo (master)
$ git status
On branch master
nothing to commit, working tree clean

Administrator@PC201501031108 MINGW64 /e/gitDemo (master)
$ echo '#我的一個git項目' >> README.md

Administrator@PC201501031108 MINGW64 /e/gitDemo (master)
$ git add .
warning: LF will be replaced by CRLF in README.md.
The file will have its original line endings in your working directory.

Administrator@PC201501031108 MINGW64 /e/gitDemo (master)
$ git commit -m 添加readme
[master 30b30aa] 添加readme
 1 file changed, 1 insertion(+)
 create mode 100644 README.md

Administrator@PC201501031108 MINGW64 /e/gitDemo (master)
$ git status
On branch master
nothing to commit, working tree clean

Administrator@PC201501031108 MINGW64 /e/gitDemo (master)
$ git remote add origin https://git.coding.net/zhangguo5/gitDemo.git

Administrator@PC201501031108 MINGW64 /e/gitDemo (master)
$ git remote
origin

Administrator@PC201501031108 MINGW64 /e/gitDemo (master)
$ git push -u origin master
Counting objects: 17, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (8/8), done.
Writing objects: 100% (17/17), 1.55 KiB | 0 bytes/s, done.
Total 17 (delta 0), reused 0 (delta 0)
To https://git.coding.net/zhangguo5/gitDemo.git
 * [new branch]      master -> master
Branch master set up to track remote branch master from origin.

Administrator@PC201501031108 MINGW64 /e/gitDemo (master)
$ e:
bash: e:: command not found

Administrator@PC201501031108 MINGW64 /e/gitDemo
$ cd ..

Administrator@PC201501031108 MINGW64 /e
$ git clone https://git.coding.net/zhangguo5/gitDemo.git
Cloning into 'gitDemo'...
remote: Counting objects: 17, done.
remote: Compressing objects: 100% (8/8), done.
remote: Total 17 (delta 0), reused 0 (delta 0)
Unpacking objects: 100% (17/17), done.

Administrator@PC201501031108 MINGW64 /e
$
View Code

示例3:

  503  clear
  504  git --version
  505  git config
  506  git config --global --list
  507  cd e:
  508  cd gitdemo
  509  cd..
  510  cd ..
  511  cd gitDemo
  512  mkdir project1
  513  rd project1
  514  rm project1
  515  rm --help
  516  rm project1 -r
  517  mkdir project1
  518  cd project1
  519  echo Hello f1.txt
  520  echo Hello > f1.txt
  521  echo Hello Git > f1.txt
  522  echo Hello Git >> f1.txt
  523  cat f1.txt
  524  echo Hello Git >> f1.txt
  525  echo Hello Git >> f1.txt
  526  cat f1.txt
  527  rm f1.txt -f
  528  clear
  529  git init #初始化倉庫
  530  cd..
  531  cd ..
  532  git init project2
  533  cd project2
  534  echo Hello Git > f1.txt
  535  cat f1.txt
  536  clear
  537  git status
  538  git add -h
  539  cls
  540  reset
  541  git add f1.txt
  542  git status
  543  git rm --cached f1.txt
  544  git status
  545  echo Hello Git >> f2.txt
  546  ls
  547  git add .
  548  git status
  549  git commit f1.txt -m 添加了f1.txt文件到本地倉庫
  550  git status
  551  git commit . -m 添加f2.txt與其它所有文件到本地倉庫
  552  echo f3.txt > f3.txt
  553  echo f4.txt > f4.txt
  554  git status
  555  git add .
  556  git commit . -m 添加所有文件(f3,f4)
  557  git commit . -m 添加所有文件f3,f4
  558  git status
  559  echo #Git上課示例 >> README.md
  560  echo 臨時文件 > temp.psd
  561  echo .psd > .gitignore
  562  git status
  563  git add .
  564  git commit -m 初始化倉庫
  565  git status
  566  git remote add origin https://git.coding.net/zhangguo5/project2.git
  567  git remote
  568  git push -u origin master
  569  echo *.psd > .gitignore
  570  cat .gitignore
  571  echo *.psd
  572  echo "*.psd" > .gitignore
  573  cat .gitignore
  574  git status
  575  git commit -m 修改了gitignore
  576  git status
  577  git commit -a -m 修改了gitignore
  578  git status
  579  git push -u origin master
  580  echo a.psd > a.psd
  581  echo b.txt > b.txt
  582  git commit -a -m 添加了b.txt與a.psd
  583  git commit -a -m 添加了b.txt與a.psd
  584  git add .
  585  git commit -a -m 添加了b.txt與a.psd
  586  git status
  587  git push -u origin master
  588  echo o "#git上課示例" > README.md
  589  git add .
  590  git commit -a -m 添加了README.md
  591  git push -u origin master
  592  echo "#git上課示例" > README.md
  593  git add .
  594  echo "#git上課示例" > README.md
  595  git commit -a -m 添加了README.md
  596  git push -u origin master
  597  git history
  598  history



mkdir project2 #創建目錄
cd project2  #進入目錄
git init  #初始化創建
echo "# project2" >> README.md  #新增一個說明文件
git add README.md
git commit -m "first commit"
git remote add origin https://git.coding.net/zhangguo5/project2.git
git push -u origin master
View Code

項目驗收標准

八、視頻

https://www.bilibili.com/video/av14813510/

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM