【讀書筆記】廖雪峰:Git教程及實(shí)操整理

1,摘要

本文是輝哥學(xué)習(xí)廖雪峰的《Git教程》的讀書筆記,把其中一些精要的命令記錄了下來。這個(gè)筆記主要給輝哥自己做備忘索引,對(duì)一般人來說很難有明了的價(jià)值,后來也根據(jù)需要增加了一些擴(kuò)展類的git命令。建議直接點(diǎn)擊學(xué)習(xí)廖雪峰的文章《Git教程》

2,GIT基本操作

2.1 安裝GIT

<1> linux
$ git
The program 'git' is currently not installed. You can install it by typing:
sudo apt-get install git

$sudo apt-get install git
<2> WINDOWS

在Windows上使用Git,可以從Git官網(wǎng)直接下載安裝程序

<3> git的幫助命令
E:\temp>git
usage: git [--version] [--help] [-C <path>] [-c <name>=<value>]
           [--exec-path[=<path>]] [--html-path] [--man-path] [--info-path]
           [-p | --paginate | -P | --no-pager] [--no-replace-objects] [--bare]
           [--git-dir=<path>] [--work-tree=<path>] [--namespace=<name>]
           <command> [<args>]

These are common Git commands used in various situations:

start a working area (see also: git help tutorial)
   clone      Clone a repository into a new directory
   init       Create an empty Git repository or reinitialize an existing one

work on the current change (see also: git help everyday)
   add        Add file contents to the index
   mv         Move or rename a file, a directory, or a symlink
   reset      Reset current HEAD to the specified state
   rm         Remove files from the working tree and from the index

examine the history and state (see also: git help revisions)
   bisect     Use binary search to find the commit that introduced a bug
   grep       Print lines matching a pattern
   log        Show commit logs
   show       Show various types of objects
   status     Show the working tree status

grow, mark and tweak your common history
   branch     List, create, or delete branches
   checkout   Switch branches or restore working tree files
   commit     Record changes to the repository
   diff       Show changes between commits, commit and working tree, etc
   merge      Join two or more development histories together
   rebase     Reapply commits on top of another base tip
   tag        Create, list, delete or verify a tag object signed with GPG

collaborate (see also: git help workflows)
   fetch      Download objects and refs from another repository
   pull       Fetch from and integrate with another repository or a local branch
   push       Update remote refs along with associated objects

'git help -a' and 'git help -g' list available subcommands and some
concept guides. See 'git help <command>' or 'git help <concept>'
to read about a specific subcommand or concept.
<4> git環(huán)境配置/獲取所有配置信息
$ git config --global user.name "duncanwang"
$ git config --global user.email "wangdenghui2005@sina.com"
$ git config -l

2.2 創(chuàng)建版本庫

<1> 創(chuàng)建文件夾

創(chuàng)建一個(gè)版本庫非常簡單,首先,選擇一個(gè)合適的地方,創(chuàng)建一個(gè)空目錄:

$ mkdir learngit
$ cd learngit
$ pwd
/Users/michael/learngit

【說明】如果你使用Windows系統(tǒng),為了避免遇到各種莫名其妙的問題,請(qǐng)確保目錄名(包括父目錄)不包含中文。

<2> git init初始化倉庫

通過git init命令把這個(gè)目錄變成Git可以管理的倉庫:

$ git init
Initialized empty Git repository in /Users/michael/learngit/.git/

【說明】當(dāng)前目錄下多了一個(gè).git的目錄,這個(gè)目錄是Git來跟蹤管理版本庫的

2.3 把文件添加到版本庫

<1> 命令git add告訴Git,把文件添加到倉庫
$ git add readme.txt

【說明】注意,可反復(fù)多次使用,添加多個(gè)文件;

【說明】
git add . :他會(huì)監(jiān)控工作區(qū)的狀態(tài)樹,使用它會(huì)把工作時(shí)的所有變化提交到暫存區(qū),包括文件內(nèi)容修改(modified)以及新文件(new),但不包括被刪除的文件。

git add -u :他僅監(jiān)控已經(jīng)被add的文件(即tracked file),他會(huì)將被修改的文件提交到暫存區(qū)。add -u 不會(huì)提交新文件(untracked file)。(git add --update的縮寫)

git add -A :是上面兩個(gè)功能的合集(git add --all的縮寫)

【完整幫助】

$ git add -h
usage: git add [<options>] [--] <pathspec>...

    -n, --dry-run         dry run
    -v, --verbose         be verbose

    -i, --interactive     interactive picking
    -p, --patch           select hunks interactively
    -e, --edit            edit current diff and apply
    -f, --force           allow adding otherwise ignored files
    -u, --update          update tracked files
    --renormalize         renormalize EOL of tracked files (implies -u)
    -N, --intent-to-add   record only the fact that the path will be added later
    -A, --all             add changes from all tracked and untracked files
    --ignore-removal      ignore paths removed in the working tree (same as --no-all)
    --refresh             don't add, only refresh the index
    --ignore-errors       just skip files which cannot be added because of errors
    --ignore-missing      check if - even missing - files are ignored in dry run
    --chmod <(+/-)x>      override the executable bit of the listed files
<2> 用命令git commit告訴Git,把文件提交到倉庫:
$ git commit -m "wrote a readme file"
[master (root-commit) eaadf4e] wrote a readme file
 1 file changed, 2 insertions(+)
 create mode 100644 readme.txt

-m 參數(shù) 表示可以直接輸入后面的“message”,如果不加 -m參數(shù),那么是不能直接輸入message的,而是會(huì)調(diào)用一個(gè)編輯器一般是vim來讓你輸入這個(gè)message,

2.4 倉庫管理

(1)運(yùn)行g(shù)it status命令看看結(jié)果

先修改readme.txt文件:

Git is a distributed version control system.
Git is free software.

然后查詢status狀態(tài):

$ 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:   readme.txt

no changes added to commit (use "git add" and/or "git commit -a")
(2)git diff查看差異

git diff查看本地和倉庫的區(qū)別。

$ git diff readme.txt 
diff --git a/readme.txt b/readme.txt
index 46d49bf..9247db6 100644
--- a/readme.txt
+++ b/readme.txt
@@ -1,2 +1,2 @@
-Git is a version control system.
+Git is a distributed version control system.
 Git is free software.
(3)git log命令查看修改記錄
$ git log
commit 1094adb7b9b3807259d8cb349e7df1d4d6477073 (HEAD -> master)
Author: Michael Liao <askxuefeng@gmail.com>
Date:   Fri May 18 21:06:15 2018 +0800

    append GPL

commit e475afc93c209a690c39c13a46716e8fa000c366
Author: Michael Liao <askxuefeng@gmail.com>
Date:   Fri May 18 21:03:36 2018 +0800

    add distributed

commit eaadf4e385e865d25c48e7ca9c8395c3f7dfaef0
Author: Michael Liao <askxuefeng@gmail.com>
Date:   Fri May 18 20:59:18 2018 +0800

    wrote a readme file

如果嫌輸出信息太多,看得眼花繚亂的,可以試試加上--pretty=oneline參數(shù):

$ git log --pretty=oneline
1094adb7b9b3807259d8cb349e7df1d4d6477073 (HEAD -> master) append GPL
e475afc93c209a690c39c13a46716e8fa000c366 add distributed
eaadf4e385e865d25c48e7ca9c8395c3f7dfaef0 wrote a readme file
(5)版本回退

我們要把當(dāng)前版本append GPL回退到上一個(gè)版本add distributed,就可以使用git reset命令:

$ git reset --hard HEAD^
HEAD is now at e475afc add distributed

在Git中,用HEAD表示當(dāng)前版本,上一個(gè)版本就是HEAD,上上一個(gè)版本就是HEAD,當(dāng)然往上100個(gè)版本寫100個(gè)比較容易數(shù)不過來,所以寫成HEAD~100。

版本恢復(fù):

$ git reset --hard 1094a
HEAD is now at 83b0afe append GPL

Git的版本回退速度非常快,因?yàn)镚it在內(nèi)部有個(gè)指向當(dāng)前版本的HEAD指針,當(dāng)你回退版本的時(shí)候,Git僅僅是把HEAD從指向append GPL:

┌────┐
│HEAD│
└────┘

└──> ○ append GPL

○ add distributed

○ wrote a readme file

改為指向add distributed:

┌────┐
│HEAD│
└────┘

│ ○ append GPL
│ │
└──> ○ add distributed

○ wrote a readme file

(5)# git 放棄本地修改,強(qiáng)制拉取更新

把HEAD指向CESI最新版本

$ git reset --hard origin/CESI
Checking out files: 100% (589/589), done.
HEAD is now at f32f2d2 log transfer befor&after
(6)命令記錄git reflog

Git提供了一個(gè)命令git reflog用來記錄你的每一次命令:

$ git reflog
e475afc HEAD@{1}: reset: moving to HEAD^
1094adb (HEAD -> master) HEAD@{2}: commit: append GPL
e475afc HEAD@{3}: commit: add distributed
eaadf4e HEAD@{4}: commit (initial): wrote a readme file

從這兒可以找到曾經(jīng)的命令,可用于恢復(fù)到新版本。

(7)版本庫(Repository)和工作區(qū)

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

本地倉庫是對(duì)于遠(yuǎn)程倉庫而言的。本地倉庫 = 工作區(qū) + 版本區(qū)。
工作區(qū)即磁盤上的文件集合。版本區(qū)(版本庫)即.git文件。

版本庫 = 暫存區(qū)(stage) + 分支(master) + 指針Head。


前面講了我們把文件往Git版本庫里添加的時(shí)候,是分兩步執(zhí)行的:

第一步是用git add把文件添加進(jìn)去,實(shí)際上就是把文件修改添加到暫存區(qū);

第二步是用git commit提交更改,實(shí)際上就是把暫存區(qū)的所有內(nèi)容提交到當(dāng)前分支。

(8)丟棄工作區(qū)和丟棄暫存區(qū)

場(chǎng)景1:當(dāng)你改亂了工作區(qū)某個(gè)文件的內(nèi)容,想直接丟棄工作區(qū)的修改時(shí),用命令git checkout -- file。

$ git checkout -- readme.txt

git checkout -- file命令中的--很重要,沒有--,就變成了“切換到另一個(gè)分支”的命令

場(chǎng)景2:當(dāng)你不但改亂了工作區(qū)某個(gè)文件的內(nèi)容,還添加到了暫存區(qū)時(shí),想丟棄修改,分兩步,第一步用命令git reset HEAD <file>,就回到了場(chǎng)景1,第二步按場(chǎng)景1操作。

$ git reset HEAD readme.txt
Unstaged changes after reset:
M    readme.txt

git reset命令既可以回退版本,也可以把暫存區(qū)的修改回退到工作區(qū)。當(dāng)我們用HEAD時(shí),表示最新的版本。

場(chǎng)景3:已經(jīng)提交了不合適的修改到版本庫時(shí),想要撤銷本次提交,參考版本回退一節(jié),不過前提是沒有推送到遠(yuǎn)程庫。

(9)刪除文件git rm

先本地刪除文件。

一是確實(shí)要從版本庫中刪除該文件,那就用命令git rm刪掉,并且git commit:

$ git rm test.txt
rm 'test.txt'

$ git commit -m "remove test.txt"
[master d46f35e] remove test.txt
 1 file changed, 1 deletion(-)
 delete mode 100644 test.txt

現(xiàn)在,文件就從版本庫中被刪除了。

另一種情況是刪錯(cuò)了,因?yàn)榘姹編炖镞€有呢,所以可以很輕松地把誤刪的文件恢復(fù)到最新版本:

$ git checkout -- test.txt

git checkout其實(shí)是用版本庫里的版本替換工作區(qū)的版本,無論工作區(qū)是修改還是刪除,都可以“一鍵還原”。

(10)刪除本地分支

<1> 查看項(xiàng)目的分支們(包括本地和遠(yuǎn)程)
命令行 : git branch -a <2>刪除本地分支 命令行 : git branch -d <BranchName>
例如: git branch -d dev

3.遠(yuǎn)程倉庫(GitHub為例)

3.1 連接遠(yuǎn)程倉庫配置GitHub

第1步:創(chuàng)建SSH Key。在用戶主目錄下,看看有沒有.ssh目錄,如果有,再看看這個(gè)目錄下有沒有id_rsa和id_rsa.pub這兩個(gè)文件,如果已經(jīng)有了,可直接跳到下一步。如果沒有,打開Shell(Windows下打開Git Bash),創(chuàng)建SSH Key:

$ ssh-keygen -t rsa -C "wangdenghui2005@sina.com"

【注意】是Git Bash運(yùn)行命令,而不是用CMD運(yùn)行命令,3次回車,不設(shè)置密碼吧。

如果一切順利的話,可以在用戶主目錄(輝哥的目錄為:C:\Users\dd)里找到.ssh目錄,有id_rsa和id_rsa.pub兩個(gè)文件,這兩個(gè)就是SSH Key的秘鑰對(duì),id_rsa是私鑰,不能泄露出去,id_rsa.pub是公鑰,可以放心地告訴任何人。

第2步:登陸GitHub,打開“Account settings”,“SSH Keys”頁面:
然后,點(diǎn)“Add SSH Key”,填上任意Title,在Key文本框里粘貼id_rsa.pub文件的內(nèi)容:

點(diǎn)“Add Key”,你就應(yīng)該看到已經(jīng)添加的Key:

3.2 添加遠(yuǎn)程庫

你已經(jīng)在本地創(chuàng)建了一個(gè)Git倉庫后,又想在GitHub創(chuàng)建一個(gè)Git倉庫,并且讓這兩個(gè)倉庫進(jìn)行遠(yuǎn)程同步。

第一步: 登陸GitHub,然后,在右上角找到“Create a new repo”按鈕,創(chuàng)建一個(gè)新的倉庫:

在Repository name填入learngit,其他保持默認(rèn)設(shè)置,點(diǎn)擊“Create repository”按鈕,就成功地創(chuàng)建了一個(gè)新的Git倉庫:

第二步: 在本地的learngit倉庫下運(yùn)行命令:

$ git remote add origin git@github.com:duncanwang/learngit.git

請(qǐng)千萬注意,把上面的duncanwang替換成你自己的GitHub賬戶名,
添加后,遠(yuǎn)程庫的名字就是origin,這是Git默認(rèn)的叫法,也可以改成別的,例如Github.

【擴(kuò)展】
假設(shè)github上已經(jīng)有master分支 和dev分支
(1)查看遠(yuǎn)端分支情況
git ls-remote

(2)在本地
git checkout -b dev 新建并切換到本地dev分支
git pull origin dev 本地分支與遠(yuǎn)程分支相關(guān)聯(lián)

(3)在本地新建分支并推送到遠(yuǎn)程
git checkout -b test
git push origin test 這樣遠(yuǎn)程倉庫中也就創(chuàng)建了一個(gè)test分支

(4)獲取遠(yuǎn)端倉庫名稱
下面語句顯示了可以抓取和推送的origin的地址。如果沒有推送權(quán)限,就看不到push的地址。

git remote -v
origin  git@github.com:michaelliao/learngit.git (fetch)
origin  git@github.com:michaelliao/learngit.git (push)

第三步,就可以把本地庫的所有內(nèi)容推送到遠(yuǎn)程庫上:

$ git push -u origin master
Counting objects: 20, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (15/15), done.
Writing objects: 100% (20/20), 1.64 KiB | 560.00 KiB/s, done.
Total 20 (delta 5), reused 0 (delta 0)
remote: Resolving deltas: 100% (5/5), done.
To github.com:michaelliao/learngit.git
 * [new branch]      master -> master
Branch 'master' set up to track remote branch 'master' from 'origin'.

【說明】我們第一次推送master分支時(shí),加上了-u參數(shù),Git不但會(huì)把本地的master分支內(nèi)容推送的遠(yuǎn)程新的master分支,還會(huì)把本地的master分支和遠(yuǎn)程的master分支關(guān)聯(lián)起來,在以后的推送或者拉取時(shí)就可以簡化命令。

E:\temp\learngit>git push -u origin master
Everything up-to-date
Branch 'master' set up to track remote branch 'master' from 'origin'.

git push的一般形式為 git push <遠(yuǎn)程主機(jī)名> <本地分支名> <遠(yuǎn)程分支名>
例如 git push origin master:refs/for/master ,即是將本地的master分支推送到遠(yuǎn)程主機(jī)origin上的對(duì)應(yīng)master分支, origin 是遠(yuǎn)程主機(jī)名。第一個(gè)master是本地分支名,第二個(gè)master是遠(yuǎn)程分支名。

git push origin master
如果遠(yuǎn)程分支被省略,如上則表示將本地分支推送到與之存在追蹤關(guān)系的遠(yuǎn)程分支(通常兩者同名),如果該遠(yuǎn)程分支不存在,則會(huì)被新建
git push origin :refs/for/master
如果省略本地分支名,則表示刪除指定的遠(yuǎn)程分支,因?yàn)檫@等同于推送一個(gè)空的本地分支到遠(yuǎn)程分支,等同于 git push origin –delete master
git push origin
如果當(dāng)前分支與遠(yuǎn)程分支存在追蹤關(guān)系,則本地分支和遠(yuǎn)程分支都可以省略,將當(dāng)前分支推送到origin主機(jī)的對(duì)應(yīng)分支
git push
如果當(dāng)前分支只有一個(gè)遠(yuǎn)程分支,那么主機(jī)名都可以省略,形如 git push,可以使用git branch -r ,查看遠(yuǎn)程的分支名

git push --set-upstream origin dev:dev
遠(yuǎn)端同名dev分支未創(chuàng)建,通過--set-upstream創(chuàng)建同名遠(yuǎn)端分支,并上傳。

3.3 從遠(yuǎn)程庫克隆

命令git clone克隆一個(gè)本地庫:

$ git clone git@github.com:duncanwang/learngit.git
Cloning into 'gitskills'...
remote: Counting objects: 3, done.
remote: Total 3 (delta 0), reused 0 (delta 0), pack-reused 3
Receiving objects: 100% (3/3), done.

這樣同時(shí)在本地也創(chuàng)建了一個(gè)同工程名稱的目錄。

如果想在本地指定一個(gè)不同于遠(yuǎn)端的目錄,可以如下:

$ git clone git@101.132.137.193:notary_group/notary_app.git notary_IOS
Cloning into 'notary_IOS'...
remote: Enumerating objects: 3302, done.
remote: Counting objects: 100% (3302/3302), done.
remote: Compressing objects: 100% (2596/2596), done.
Receiving objects:   1% (48/3302), 2.90 MiB | 593.00 KiB/s

補(bǔ)充知識(shí):
(1) https的命令
git clone https://github.com/duncanwang/learngit
(2) 直接檢出分支
git clone -b dev https://github.com/duncanwang/learngit
(3) 修改上行origin的名稱
git clone -o test http://git.ju3ban.net/duncanwang/duncanwangtest.git
(4) 修改下載的本地工程名稱
git clone http://git.ju3ban.net/duncanwang/duncanwangtest.git temptest
(5) github工程文件很大情況,推薦只下載一個(gè)版本分支
git clone -b dev --single-branch https://github.com/duncanwang/learngit
(6) gitclone下載某一個(gè)標(biāo)簽項(xiàng)目
git clone --branch v1.2.0 https://github.com/hyperledger/fabric.git

3.4 變更遠(yuǎn)程倉庫IP地址

先參考3.1 完成SSH賬號(hào)配置。

(1)查看原來的遠(yuǎn)程倉庫地址:

$ git remote -v
origin  git@git.ju3ban.net:duncanwang/copyrightchain.git (fetch)
origin  git@git.ju3ban.net:duncanwang/copyrightchain.git (push)

(2)變更地址

$ git remote set-url origin  git@101.132.137.193:duncanwang/copyrightchain.git

(3)查看新的地址

$ git remote -v
origin  git@101.132.137.193:8686:duncanwang/copyrightchain.git (fetch)
origin  git@101.132.137.193:8686:duncanwang/copyrightchain.git (push)

4. 分支管理

4.1 創(chuàng)建與合并分支概念

一開始的時(shí)候,master分支是一條線,Git用master指向最新的提交,再用HEAD指向master,就能確定當(dāng)前分支,以及當(dāng)前分支的提交點(diǎn):

當(dāng)我們創(chuàng)建新的分支,例如dev時(shí),Git新建了一個(gè)指針叫dev,指向master相同的提交,再把HEAD指向dev,就表示當(dāng)前分支在dev上:

從現(xiàn)在開始,對(duì)工作區(qū)的修改和提交就是針對(duì)dev分支了,比如新提交一次后,dev指針往前移動(dòng)一步,而master指針不變:

4.2 創(chuàng)建分支git checkout -b

我們創(chuàng)建dev分支,然后切換到dev分支:

$ git checkout -b dev
Switched to a new branch 'dev'

git checkout命令加上-b參數(shù)表示創(chuàng)建并切換,相當(dāng)于以下兩條命令:

$ git branch dev
$ git checkout dev
Switched to branch 'dev'

4.3 查看分支git branch

$ git branch
* dev
  master

4.3 查看本地分支和遠(yuǎn)程分支的跟蹤關(guān)系

$ git branch -vv
  dev        29a9cfb Merge branch 'dev' of http://git.ju3ban.net/duncanwang/copy                                                                                                                rightchain into dev
* fix_v1.2.0 38a045e [origin/fix_v1.2.0: ahead 2, behind 9] Merge branch 'fix_v1                                                                                                                .2.0' of http://git.ju3ban.net/duncanwang/copyrightchain into fix_v1.2.0
  list       4870278 add smart contract src
  master     aa893d4 [origin/master: behind 87] add passwd config

4.4 合并分支git merge

我們就可以在dev分支上正常提交,比如對(duì)readme.txt做個(gè)修改,加上一行:

Creating a new branch is quick.

然后提交:

$ git add readme.txt 
$ git commit -m "branch test"
[dev b17d20e] branch test
 1 file changed, 1 insertion(+)

現(xiàn)在,dev分支的工作完成,我們就可以切換回master分支:

$ git checkout master
Switched to branch 'master'

切換回master分支后,再查看一個(gè)readme.txt文件,剛才添加的內(nèi)容不見了!因?yàn)槟莻€(gè)提交是在dev分支上,而master分支此刻的提交點(diǎn)并沒有變:

現(xiàn)在,我們把dev分支的工作成果合并到master分支上:

$ git merge dev
Updating d46f35e..b17d20e
Fast-forward
 readme.txt | 1 +
 1 file changed, 1 insertion(+)

git merge命令用于合并指定分支到當(dāng)前分支。合并后,再查看readme.txt的內(nèi)容,就可以看到,和dev分支的最新提交是完全一樣的。

注意到上面的Fast-forward信息,Git告訴我們,這次合并是“快進(jìn)模式”,也就是直接把master指向dev的當(dāng)前提交,所以合并速度非常快。

當(dāng)然,也不是每次合并都能Fast-forward,我們后面會(huì)講其他方式的合并。

【補(bǔ)充】
(1) 運(yùn)行g(shù)it-merge時(shí)含有大量的未commit文件很容易讓你陷入困境,這將使你在沖突中難以回退。因此非常不鼓勵(lì)在使用git-merge時(shí)存在未commit的文件,建議使用git-stash命令將這些未commit文件暫存起來,并在解決沖突以后使用git stash pop把這些未commit文件還原出來。
git stash
git stash pop
(2)git merge --abort命令
該命令僅僅在合并后導(dǎo)致沖突時(shí)才使用。git merge --abort將會(huì)拋棄合并過程并且嘗試重建合并前的狀態(tài)。但是,當(dāng)合并開始時(shí)如果存在未commit的文件,git merge --abort在某些情況下將無法重現(xiàn)合并前的狀態(tài)。(特別是這些未commit的文件在合并的過程中將會(huì)被修改時(shí))。

4.5 刪除分支git branch -d

$ git branch -d dev
Deleted branch dev (was b17d20e).

刪除后,查看branch,就只剩下master分支了:

$ git branch
* master

4.6 解決沖突

準(zhǔn)備新的feature1分支,繼續(xù)我們的新分支開發(fā):

$ git checkout -b feature1
Switched to a new branch 'feature1'

修改readme.txt最后一行,改為:

Creating a new branch is quick AND simple.

在feature1分支上提交:

$ git add readme.txt

$ git commit -m "AND simple"
[feature1 14096d0] AND simple
 1 file changed, 1 insertion(+), 1 deletion(-)

切換到master分支:

$ git checkout master
Switched to branch 'master'
Your branch is ahead of 'origin/master' by 1 commit.
  (use "git push" to publish your local commits)

Git還會(huì)自動(dòng)提示我們當(dāng)前master分支比遠(yuǎn)程的master分支要超前1個(gè)提交。

在master分支上把readme.txt文件的最后一行改為:

Creating a new branch is quick & simple.

提交:

$ git add readme.txt 
$ git commit -m "& simple"
[master 5dc6824] & simple
 1 file changed, 1 insertion(+), 1 deletion(-)

現(xiàn)在,master分支和feature1分支各自都分別有新的提交,變成了這樣:



這種情況下,Git無法執(zhí)行“快速合并”,只能試圖把各自的修改合并起來,但這種合并就可能會(huì)有沖突,我們?cè)囋嚳矗?/p>

$ git merge feature1
Auto-merging readme.txt
CONFLICT (content): Merge conflict in readme.txt
Automatic merge failed; fix conflicts and then commit the result.

果然沖突了!Git告訴我們,readme.txt文件存在沖突,必須手動(dòng)解決沖突后再提交。git status也可以告訴我們沖突的文件:

$ git status
On branch master
Your branch is ahead of 'origin/master' by 2 commits.
  (use "git push" to publish your local commits)

You have unmerged paths.
  (fix conflicts and run "git commit")
  (use "git merge --abort" to abort the merge)

Unmerged paths:
  (use "git add <file>..." to mark resolution)

    both modified:   readme.txt

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

我們可以直接查看readme.txt的內(nèi)容:

Git is a distributed version control system.
Git is free software distributed under the GPL.
Git has a mutable index called stage.
Git tracks changes of files.
<<<<<<< HEAD
Creating a new branch is quick & simple.
=======
Creating a new branch is quick AND simple.
>>>>>>> feature1

Git用<<<<<<<,=======,>>>>>>>標(biāo)記出不同分支的內(nèi)容,我們修改如下后保存:

Creating a new branch is quick and simple.

再提交:

$ git add readme.txt 
$ git commit -m "conflict fixed"
[master cf810e4] conflict fixed

現(xiàn)在,master分支和feature1分支變成了下圖所示:


用帶參數(shù)的git log也可以看到分支的合并情況:

$ git log --graph --pretty=oneline --abbrev-commit
*   cf810e4 (HEAD -> master) conflict fixed
|\  
| * 14096d0 (feature1) AND simple
* | 5dc6824 & simple
|/  
* b17d20e branch test
* d46f35e (origin/master) remove test.txt
* b84166e add test.txt
* 519219b git tracks changes
* e43a48b understand how stage works
* 1094adb append GPL
* e475afc add distributed
* eaadf4e wrote a readme file

git rebase

git rebase操作可以把本地多次commit 但是未push的分叉提交歷史整理成直線;
git rebase的目的是使得我們?cè)诓榭礆v史提交的變化時(shí)更容易,因?yàn)榉植娴奶峤恍枰綄?duì)比。

例如,用git log看提交記錄如下:

$ git log --graph --pretty=oneline --abbrev-commit
*   e0ea545 (HEAD -> master) Merge branch 'master' of github.com:michaelliao/learngit
|\  
| * f005ed4 (origin/master) set exit=1
* | 582d922 add author
* | 8875536 add comment
|/  
* d1be385 init hello
...

此時(shí),執(zhí)行rebase命令:

$ git rebase
First, rewinding head to replay your work on top of it...
Applying: add comment
Using index info to reconstruct a base tree...
M   hello.py
Falling back to patching base and 3-way merge...
Auto-merging hello.py
Applying: add author
Using index info to reconstruct a base tree...
M   hello.py
Falling back to patching base and 3-way merge...
Auto-merging hello.py

再用git log看看:

$ git log --graph --pretty=oneline --abbrev-commit
* 7e61ed4 (HEAD -> master) add author
* 3611cfe add comment
* f005ed4 (origin/master) set exit=1
* d1be385 init hello
...

原本分叉的提交現(xiàn)在變成一條直線了!這種神奇的操作是怎么實(shí)現(xiàn)的?其實(shí)原理非常簡單。我們注意觀察,發(fā)現(xiàn)Git把我們本地的提交“挪動(dòng)”了位置,放到了f005ed4 (origin/master) set exit=1之后,這樣,整個(gè)提交歷史就成了一條直線。rebase操作前后,最終的提交內(nèi)容是一致的,但是,我們本地的commit修改內(nèi)容已經(jīng)變化了,它們的修改不再基于d1be385 init hello,而是基于f005ed4 (origin/master) set exit=1,但最后的提交7e61ed4內(nèi)容是一致的。

這就是rebase操作的特點(diǎn):把分叉的提交歷史“整理”成一條直線,看上去更直觀。缺點(diǎn)是本地的分叉提交已經(jīng)被修改過了。

4.7 分支管理策略

通常,合并分支時(shí),如果可能,Git會(huì)用Fast forward模式,但這種模式下,刪除分支后,會(huì)丟掉分支信息。

如果要強(qiáng)制禁用Fast forward模式,Git就會(huì)在merge時(shí)生成一個(gè)新的commit,這樣,從分支歷史上就可以看出分支信息。

下面我們實(shí)戰(zhàn)一下--no-ff方式的git merge:

首先,仍然創(chuàng)建并切換dev分支:

$ git checkout -b dev
Switched to a new branch 'dev'

修改readme.txt文件,并提交一個(gè)新的commit:

$ git add readme.txt 
$ git commit -m "add merge"
[dev f52c633] add merge
 1 file changed, 1 insertion(+)

現(xiàn)在,我們切換回master:

$ git checkout master
Switched to branch 'master'

準(zhǔn)備合并dev分支,請(qǐng)注意--no-ff參數(shù),表示禁用Fast forward:

$ git merge --no-ff -m "merge with no-ff" dev
Merge made by the 'recursive' strategy.
 readme.txt | 1 +
 1 file changed, 1 insertion(+)

因?yàn)楸敬魏喜⒁獎(jiǎng)?chuàng)建一個(gè)新的commit,所以加上-m參數(shù),把commit描述寫進(jìn)去。
合并后,我們用git log看看分支歷史:

$ git log --graph --pretty=oneline --abbrev-commit
*   e1e9c68 (HEAD -> master) merge with no-ff
|\  
| * f52c633 (dev) add merge
|/  
*   cf810e4 conflict fixed
...

可以看到,不使用Fast forward模式,merge后就像這樣:


分支策略

首先,master分支應(yīng)該是非常穩(wěn)定的,也就是僅用來發(fā)布新版本,平時(shí)不能在上面干活;

那在哪干活呢?干活都在dev分支上,也就是說,dev分支是不穩(wěn)定的,到某個(gè)時(shí)候,比如1.0版本發(fā)布時(shí),再把dev分支合并到master上,在master分支發(fā)布1.0版本;

你和你的小伙伴們每個(gè)人都在dev分支上干活,每個(gè)人都有自己的分支,時(shí)不時(shí)地往dev分支上合并就可以了。

所以,團(tuán)隊(duì)合作的分支看起來就像這樣:

git-br-policy

4.8 保存工作現(xiàn)場(chǎng)git stash

Git還提供了一個(gè)stash功能,可以把當(dāng)前工作現(xiàn)場(chǎng)“儲(chǔ)藏”起來,等以后恢復(fù)現(xiàn)場(chǎng)后繼續(xù)工作:

$ git stash
Saved working directory and index state WIP on dev: f52c633 add merge

用git stash list命令看看:

$ git stash list
stash@{0}: WIP on dev: f52c633 add merge

工作現(xiàn)場(chǎng)還在,Git把stash內(nèi)容存在某個(gè)地方了,但是需要恢復(fù)一下,有兩個(gè)辦法:

一是用git stash apply恢復(fù),但是恢復(fù)后,stash內(nèi)容并不刪除,你需要用git stash drop來刪除;

另一種方式是用git stash pop,恢復(fù)的同時(shí)把stash內(nèi)容也刪了:

$ git stash pop
On branch dev
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

    new file:   hello.py

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:   readme.txt

Dropped refs/stash@{0} (5d677e2ee266f39ea296182fb2354265b91b3b2a)

你可以多次stash,恢復(fù)的時(shí)候,先用git stash list查看,然后恢復(fù)指定的stash,用命令:

$ git stash apply stash@{0}

【補(bǔ)充】
(1)清空所有儲(chǔ)藏區(qū)
git stash clear
(2)刪除某個(gè)儲(chǔ)藏激勵(lì)
git stash drop stash@{0}

4.9 cherry-pick選擇變更

使用 cherry-pick,可以從其他分支復(fù)制指定的提交,然后導(dǎo)入到現(xiàn)在的分支。
主要使用的場(chǎng)合:
把弄錯(cuò)分支的提交移動(dòng)到正確的地方
把其他分支的提交添加到現(xiàn)在的分支
例如,我們想把 learn-cherry-pick 這個(gè)分支上的第二個(gè)提交提取出來,然后添加到 master 上。



首先從圖右部分可以找到我們想提取 commit 的 commit id 為 c3f0d9a,在 master 分支上執(zhí)行 cherry-pick。
操作如下:

 git cherry-pick c3f0d9a
[master 573066e] add a new line
 Date: Sun Jan 14 18:50:20 2018 +0800
 1 file changed, 1 insertion(+)

結(jié)果:


cherry-pick 過程中也是可能會(huì)產(chǎn)生沖突的,解決沖突后先 add,然后使用 git cherry-pick --continue。
如果想放棄 cherry-pick,使用 git cherry-pick --abort

然后走git add,git commit,git push把變更推送到遠(yuǎn)端。

4.9 多人協(xié)作git push

(1)推送分支git push

推送分支,就是把該分支上的所有本地提交推送到遠(yuǎn)程庫。推送時(shí),要指定本地分支,這樣,Git就會(huì)把該分支推送到遠(yuǎn)程庫對(duì)應(yīng)的遠(yuǎn)程分支上:

$ git push origin master

如果要推送其他分支,比如dev,就改成:

$ git push origin dev

但是,并不是一定要把本地分支往遠(yuǎn)程推送,那么,哪些分支需要推送,哪些不需要呢?

  • master分支是主分支,因此要時(shí)刻與遠(yuǎn)程同步;

  • dev分支是開發(fā)分支,團(tuán)隊(duì)所有成員都需要在上面工作,所以也需要與遠(yuǎn)程同步;

  • bug分支只用于在本地修復(fù)bug,就沒必要推到遠(yuǎn)程了,除非老板要看看你每周到底修復(fù)了幾個(gè)bug;

  • feature分支是否推到遠(yuǎn)程,取決于你是否和你的小伙伴合作在上面開發(fā)。

總之,就是在Git中,分支完全可以在本地自己藏著玩,是否推送,視你的心情而定!

抓取分支

多人協(xié)作時(shí),大家都會(huì)往master和dev分支上推送各自的修改。

現(xiàn)在,你的小伙伴要在dev分支上開發(fā),就必須創(chuàng)建遠(yuǎn)程origin的dev分支到本地,于是他用這個(gè)命令創(chuàng)建本地dev分支:

$ git checkout -b dev origin/dev

現(xiàn)在,他就可以在dev上繼續(xù)修改,然后,時(shí)不時(shí)地把dev分支push到遠(yuǎn)程:

$ git add env.txt

$ git commit -m "add env"
[dev 7a5e5dd] add env
 1 file changed, 1 insertion(+)
 create mode 100644 env.txt

$ git push origin dev
Counting objects: 3, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 308 bytes | 308.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To github.com:michaelliao/learngit.git
   f52c633..7a5e5dd  dev -> dev

后面你修改后push時(shí)出現(xiàn)推送失敗,因?yàn)槟愕男』锇榈淖钚绿峤缓湍阍噲D推送的提交有沖突,解決辦法也很簡單,Git已經(jīng)提示我們,先用git pull把最新的提交從origin/dev抓下來,然后,在本地合并,解決沖突,再推送:

$ git pull
There is no tracking information for the current branch.
Please specify which branch you want to merge with.
See git-pull(1) for details.

    git pull <remote> <branch>

If you wish to set tracking information for this branch you can do so with:

    git branch --set-upstream-to=origin/<branch> dev

git pull也失敗了,原因是沒有指定本地dev分支與遠(yuǎn)程origin/dev分支的鏈接,根據(jù)提示,設(shè)置dev和origin/dev的鏈接:

$ git branch --set-upstream-to=origin/dev dev
Branch 'dev' set up to track remote branch 'dev' from 'origin'.

再pull:

$ git pull
Auto-merging env.txt
CONFLICT (add/add): Merge conflict in env.txt
Automatic merge failed; fix conflicts and then commit the result.

這回git pull成功,但是合并有沖突,需要手動(dòng)解決,解決的方法和分支管理中的解決沖突完全一樣。解決后,提交,再push:

$ git commit -m "fix env conflict"
[dev 57c53ab] fix env conflict

$ git push origin dev
Counting objects: 6, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (4/4), done.
Writing objects: 100% (6/6), 621 bytes | 621.00 KiB/s, done.
Total 6 (delta 0), reused 0 (delta 0)
To github.com:michaelliao/learngit.git
   7a5e5dd..57c53ab  dev -> dev

因此,多人協(xié)作的工作模式通常是這樣:

  • 首先,可以試圖用git push origin <branch-name>推送自己的修改;

  • 如果推送失敗,則因?yàn)檫h(yuǎn)程分支比你的本地更新,需要先用git pull試圖合并;

  • 如果合并有沖突,則解決沖突,并在本地提交;

  • 沒有沖突或者解決掉沖突后,再用git push origin <branch-name>推送就能成功!

如果git pull提示no tracking information,則說明本地分支和遠(yuǎn)程分支的鏈接關(guān)系沒有創(chuàng)建,用命令git branch --set-upstream-to <branch-name> origin/<branch-name>。

這就是多人協(xié)作的工作模式,一旦熟悉了,就非常簡單。

git pull 和git fetch的區(qū)別?

(1)git pull格式

git pull <遠(yuǎn)程主機(jī)名> <遠(yuǎn)程分支名>:<本地分支名>
git pull origin master:master

git pull拉取遠(yuǎn)程分之后直接與本地分支進(jìn)行合并。更準(zhǔn)確地說,git pull使用給定的參數(shù)運(yùn)行g(shù)it fetch,并調(diào)用git merge將檢索到的分支頭合并到當(dāng)前分支中。
(2) git fetch

git fetch <遠(yuǎn)程主機(jī)名> <分支名>
例如,
git fetch origin master
然后使用git merge命令或者git rebase命令,在本地分支上合并遠(yuǎn)程分支。
git merge origin/master
或者
git rebase origin/master

(3)git 放棄本地修改,強(qiáng)制拉取更新

git fetch --all
git reset --hard origin/master

或者

git pull --force <遠(yuǎn)程主機(jī)名> <遠(yuǎn)程分支名>:<本地分支名>

5. 標(biāo)簽管理

5.1 創(chuàng)建標(biāo)簽git tag

在Git中打標(biāo)簽非常簡單,首先,切換到需要打標(biāo)簽的分支上:

$ git branch
* dev
  master
$ git checkout master
Switched to branch 'master'

然后,敲命令git tag <name>就可以打一個(gè)新標(biāo)簽:

// git tag -a 標(biāo)簽名稱 -m "說明"

$ git tag -a v1.0.0  -m '消息內(nèi)容'

可以用命令git tag查看所有標(biāo)簽:

$ git tag
v1.0

推送標(biāo)簽上傳到服務(wù)器。

$git push origin v1.0.0 

默認(rèn)標(biāo)簽是打在最新提交的commit上的。有時(shí)候,如果忘了打標(biāo)簽,比如,現(xiàn)在已經(jīng)是周五了,但應(yīng)該在周一打的標(biāo)簽沒有打,怎么辦?

方法是找到歷史提交的commit id,然后打上就可以了:

$ git log --pretty=oneline --abbrev-commit
12a631b (HEAD -> master, tag: v1.0, origin/master) merged bug fix 101
4c805e2 fix bug 101
e1e9c68 merge with no-ff
f52c633 add merge
cf810e4 conflict fixed
5dc6824 & simple
14096d0 AND simple
b17d20e branch test
d46f35e remove test.txt
b84166e add test.txt
519219b git tracks changes
e43a48b understand how stage works
1094adb append GPL
e475afc add distributed
eaadf4e wrote a readme file

比方說要對(duì)add merge這次提交打標(biāo)簽,它對(duì)應(yīng)的commit id是f52c633,敲入命令:

$ git tag v0.9 f52c633

再用命令git tag查看標(biāo)簽:

$ git tag
v0.9
v1.0

注意,標(biāo)簽不是按時(shí)間順序列出,而是按字母排序的??梢杂胓it show <tagname>查看標(biāo)簽信息:

$ git show v0.9
commit f52c63349bc3c1593499807e5c8e972b82c8f286 (tag: v0.9)
Author: Michael Liao <askxuefeng@gmail.com>
Date:   Fri May 18 21:56:54 2018 +0800

    add merge

diff --git a/readme.txt b/readme.txt
...

還可以創(chuàng)建帶有說明的標(biāo)簽,用-a指定標(biāo)簽名,-m指定說明文字:

$ git tag -a v0.1 -m "version 0.1 released" 1094adb

【注意:】標(biāo)簽總是和某個(gè)commit掛鉤。如果這個(gè)commit既出現(xiàn)在master分支,又出現(xiàn)在dev分支,那么在這兩個(gè)分支上都可以看到這個(gè)標(biāo)簽。

以上命令在項(xiàng)目倉庫創(chuàng)建了一個(gè)v1.0的release,如下圖:

image

5.2 刪除標(biāo)簽或者推送標(biāo)簽

如果標(biāo)簽打錯(cuò)了,也可以刪除:

$ git tag -d v0.1
Deleted tag 'v0.1' (was f15b0dd)

因?yàn)閯?chuàng)建的標(biāo)簽都只存儲(chǔ)在本地,不會(huì)自動(dòng)推送到遠(yuǎn)程。所以,打錯(cuò)的標(biāo)簽可以在本地安全刪除。

如果要推送某個(gè)標(biāo)簽到遠(yuǎn)程,使用命令git push origin <tagname>:

$ git push origin v1.0
Total 0 (delta 0), reused 0 (delta 0)
To github.com:michaelliao/learngit.git
 * [new tag]         v1.0 -> v1.0

或者,一次性推送全部尚未推送到遠(yuǎn)程的本地標(biāo)簽:

$ git push origin --tags
Total 0 (delta 0), reused 0 (delta 0)
To github.com:michaelliao/learngit.git
 * [new tag]         v0.9 -> v0.9

如果標(biāo)簽已經(jīng)推送到遠(yuǎn)程,要?jiǎng)h除遠(yuǎn)程標(biāo)簽就麻煩一點(diǎn),先從本地刪除:

$ git tag -d v0.9
Deleted tag 'v0.9' (was f52c633)

然后,從遠(yuǎn)程刪除。刪除命令也是push,但是格式如下:

$ git push origin :refs/tags/v0.9
To github.com:michaelliao/learngit.git
 - [deleted]         v0.9

要看看是否真的從遠(yuǎn)程庫刪除了標(biāo)簽,可以登陸GitHub查看。

6,搭建Git服務(wù)器

遠(yuǎn)程倉庫一節(jié)中,我們講了遠(yuǎn)程倉庫實(shí)際上和本地倉庫沒啥不同,純粹為了7x24小時(shí)開機(jī)并交換大家的修改。

GitHub就是一個(gè)免費(fèi)托管開源代碼的遠(yuǎn)程倉庫。但是對(duì)于某些視源代碼如生命的商業(yè)公司來說,既不想公開源代碼,又舍不得給GitHub交保護(hù)費(fèi),那就只能自己搭建一臺(tái)Git服務(wù)器作為私有倉庫使用。

搭建Git服務(wù)器需要準(zhǔn)備一臺(tái)運(yùn)行Linux的機(jī)器,強(qiáng)烈推薦用Ubuntu或Debian,這樣,通過幾條簡單的apt命令就可以完成安裝。

假設(shè)你已經(jīng)有sudo權(quán)限的用戶賬號(hào),下面,正式開始安裝。

第一步,安裝git

$ sudo apt-get install git

第二步,創(chuàng)建一個(gè)git用戶,用來運(yùn)行git服務(wù):

$ sudo adduser git

第三步,創(chuàng)建證書登錄:

收集所有需要登錄的用戶的公鑰,就是他們自己的id_rsa.pub文件,把所有公鑰導(dǎo)入到/home/git/.ssh/authorized_keys文件里,一行一個(gè)。

第四步,初始化Git倉庫:

先選定一個(gè)目錄作為Git倉庫,假定是/srv/sample.git,在/srv目錄下輸入命令:

$ sudo git init --bare sample.git

Git就會(huì)創(chuàng)建一個(gè)裸倉庫,裸倉庫沒有工作區(qū),因?yàn)榉?wù)器上的Git倉庫純粹是為了共享,所以不讓用戶直接登錄到服務(wù)器上去改工作區(qū),并且服務(wù)器上的Git倉庫通常都以.git結(jié)尾。然后,把owner改為git

$ sudo chown -R git:git sample.git

第五步,禁用shell登錄:

出于安全考慮,第二步創(chuàng)建的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,因?yàn)槲覀優(yōu)?code>git用戶指定的git-shell每次一登錄就自動(dòng)退出。

第六步,克隆遠(yuǎn)程倉庫:

現(xiàn)在,可以通過git clone命令克隆遠(yuǎn)程倉庫了,在各自的電腦上運(yùn)行:

$ git clone git@server:/srv/sample.git
Cloning into 'sample'...
warning: You appear to have cloned an empty repository.

剩下的推送就簡單了。

管理公鑰

如果團(tuán)隊(duì)很小,把每個(gè)人的公鑰收集起來放到服務(wù)器的/home/git/.ssh/authorized_keys文件里就是可行的。如果團(tuán)隊(duì)有幾百號(hào)人,就沒法這么玩了,這時(shí),可以用Gitosis來管理公鑰。

這里我們不介紹怎么玩Gitosis了,幾百號(hào)人的團(tuán)隊(duì)基本都在500強(qiáng)了,相信找個(gè)高水平的Linux管理員問題不大。

管理權(quán)限

有很多不但視源代碼如生命,而且視員工為竊賊的公司,會(huì)在版本控制系統(tǒng)里設(shè)置一套完善的權(quán)限控制,每個(gè)人是否有讀寫權(quán)限會(huì)精確到每個(gè)分支甚至每個(gè)目錄下。因?yàn)镚it是為Linux源代碼托管而開發(fā)的,所以Git也繼承了開源社區(qū)的精神,不支持權(quán)限控制。不過,因?yàn)镚it支持鉤子(hook),所以,可以在服務(wù)器端編寫一系列腳本來控制提交等操作,達(dá)到權(quán)限控制的目的。Gitolite就是這個(gè)工具。

這里我們也不介紹Gitolite了,不要把有限的生命浪費(fèi)到權(quán)限斗爭(zhēng)中。

7. 進(jìn)階操作

此處只列出目錄,有需要的從搜索引擎搜索內(nèi)容即可獲得解決方案。


8,參考

(1)廖雪峰的Git教程
https://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017b000

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Git 是目前最流行的分布式版本控制系統(tǒng)之一。 版本控制指的是,記錄每次版本變更的內(nèi)容和時(shí)間等細(xì)節(jié),保留各版本之間...
    神齊閱讀 1,508評(píng)論 0 7
  • chapter 1: 如何創(chuàng)建版本庫 初始化一個(gè)倉庫 $ git init 添加文件到Git倉庫的過程: $ gi...
    飛將軍閱讀 3,043評(píng)論 0 2
  • 原文地址主要用到的命令: git config user.name 設(shè)置用戶名 git config user....
    AFinalStone閱讀 565評(píng)論 0 2
  • 如何關(guān)聯(lián)遠(yuǎn)程庫? 1.新建本地庫 2.通過git官網(wǎng)新建遠(yuǎn)程庫 3.輸入指令: git remote add or...
    諸子大人閱讀 17,517評(píng)論 1 9
  • 吃了麻辣香鍋咳嗽了n天之后,(其實(shí)也不止麻辣香鍋啦,還有家里各種小蛋糕,網(wǎng)紅雪花餅)我爸看我咳嗽還沒好,我媽也感冒...
    Sarea_H閱讀 234評(píng)論 0 0

友情鏈接更多精彩內(nèi)容