Git使用,實戰版

Git安裝

Git配置

配置快捷命令

  • 在用戶根目錄下(如C:/user/Administrator)新建配置文件命名為.gitconfig
  • 將以下內容寫入文件
[user]
    email = xxx(郵箱如:foxleezh@gmail.com)
    name = xxx(名字如:foxleezh)
[alias]
    st = status
    ci = commit
    br = branch
    co = checkout
    glog = log --pretty=oneline
    pus = push
    pul = !git pull --rebase && git submodule update --init --recursive
    lg = log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit
[merge]
    tool = vim
[core]
    packedGitLimit = 512m
    packedGitWindowSize = 512m
[pack]
    deltaCacheSize = 2047m
    packSizeLimit = 2047m
    windowMemory = 2047m

配置ssh

  • 在命令行輸入
ssh-keygen -t rsa
  • 在用戶目錄(如C:/user/Administrator)打開.ssh文件夾,查看id_rsa.pub文件,將密鑰拷貝到服務器密鑰庫

配置忽略文件

  • 將.gitignore文件放置到項目根目錄下
# OSX

*.DS_Store


# Gradle files
build/
build_out/
obj/
.gradle/
*/build/
captures/

gradle/
# IDEA
*.iml
.idea/.name
.idea/encodings.xml
.idea/inspectionProfiles/Project_Default.xml
.idea/inspectionProfiles/profiles_settings.xml
.idea/misc.xml
.idea/modules.xml
.idea/scopes/scope_settings.xml
.idea/vcs.xml
.idea/workspace.xml
.idea/libraries
.idea/runConfigurations.xml
.idea/compiler.xml
.idea/copyright/profiles_settings.xml
.idea/gradle.xml
.idea/

# Built application files
*.ap_


# Files for the Dalvik VM
*.dex


# Java class files
*.class


# Local configuration file (sdk path, etc)
local.properties


# Log Files
*.log

# Special
gradle.properties
  • 凡是在列表中的文件(*表示所有)都將被git忽略,對這些文件的任何改動,git都不會追蹤
  • 但是有時我們只想追蹤某幾個文件,其它都忽略,可以如下配置,!后面的內容為追蹤的文件
/*
!.gitignore
!README.md

Git使用

一.準備工作

  • 新建倉庫(進入到項目的根目錄下)
git init
  • 添加忽略規則,將.gitignore文件放置到根目錄下
  • 添加文件,將需要管理的文件加入到根目錄下

二.代碼管理

  • 查看狀態
git st

紅色表示已修改未保存到緩存區,綠色表示已保存到緩存區

Git有三個狀態,一是修改未保存到緩存,二是保存到緩存,三是提交到版本庫

我們可以對比著word文檔來學習,狀態一就相當于你在word中修改了一些東西,但是沒有按ctrl+s鍵保存起來,狀態二就是你修改了東西后按了ctrl+s,暫時存起來了,狀態三就是點擊了另存為,將它另外存放起來了

  • 保存到緩存區
git add 文件路徑(添加單個文件到緩存)

一開始修改了homepage和loading兩個文件,git st后顯示紅色

使用git add后,將homepage加入到緩存區

git st后,發現homepage變為綠色

git add -u(添加所有修改到緩存)

一開始修改了homepage和loading兩個文件,git st后顯示紅色

使用git add -u后,將homepage和loading一起加入到緩存區

git st后,發現homepage和loading變為綠色

git add . (添加所有文件到緩存,包括新建的文件)

此用法與git add -u類似,區別在于,git add -u只能將修改的文件加入緩存,如果該文件是新建的,要使用git add ., 這個“.”符號表示所有

  • 撤銷緩存區的文件
     git reset 文件路徑(撤銷單個文件)

首先git st后發現,有兩個已經加入到緩存區的homepage和loading文件

使用git reset homepage后,將homepage文件撤銷

git st后發現,homepage變為紅色

git reset(撤銷所有緩存區的文件)

首先git st后發現,有兩個已經加入到緩存區的homepage和loading文件

使用git reset后,將所有文件撤銷

git st后發現,homepage和loading都變為紅色

  • 撤銷修改
git co 文件路徑(撤銷單個文件的修改)

首先使用git st,發現有homepage和loading兩個文件被修改

使用git co homepage,撤銷homepage的修改

git st后發現homepage文件不見了,查看原代碼,代碼中的修改也沒有了

git reset --hard (撤銷所有文件的修改)

首先使用git st,發現有homepage和loading兩個文件被修改

使用git reset --hard,撤銷所有的修改

git st后發現homepage和loading文件不見了,顯示nothing to commit,working directory clean, 這表示當前沒有任何的修改

  • 查看修改的內容
git diff 文件路徑(查看單個文件修改)

首先使用git st,有兩個文件Homepage,loading被修改

使用git diff homepage,可以看到哪些被修改了,按箭頭上下可以翻動,”-”號表示刪除(紅色顯示),”+”號表示添加(紅色顯示)

查看完成后輸入q,即可退出查看

要查看所有修改直接用git diff

git diff --cached (查看處于緩存區的修改)

首先使用git st,有兩個文件Homepage,loading被加入到緩存區

使用git diff homepage,可以看到哪些被修改了,按箭頭上下可以翻動,”-”號表示刪除(紅色顯示),”+”號表示添加(紅色顯示)

查看完成后輸入q,即可退出查看

要查看所有修改直接用git diff --cached

  • 將緩存區的內容提交到版本庫
git ci -m “我修改了什么”

首先git st,發現有兩個文件homepage和loading加入到緩存區

使用git ci -m “注釋”,將緩存區的內容提交到版本庫,這里注釋是隨便寫的,用于提示該commit修改了一些什么內容

git st后發現,緩存區中的內容不見了,這是因為已經提交到版本庫中了

  • 查看版本庫中的內容
git log

git log后發現有兩個提交,“我修改了什么”是剛剛提交的commit,下面來分析下:

commit ac76744b1843665d0c6cf1add7cf758bc824c89a (這行是一個md5值,用來唯一標識commit的)

Author: foxleezh foxleezh@gmail.com (這行是說明該commit是誰提交的)

Date: Fri Jul 10 10:02:16 2015 +0800 (提交的時間)

我修改了什么 (之前我們寫的注釋)

  • 查看某個提交中修改的內容
git show commit號

git show ac76744b, 這個ac76744b就是之前git log時對應的md5值,可以只取前6位

查看完成用q退出

我們回顧一下已講的內容,一般來說使用流程都是

  • 修改了一些內容,用git st看看狀態
  • git diff看看修改了哪些內容
  • 確認無誤后,將需要提交的內容git add加入到緩存區
  • git ci -m 加入到版本庫中,這里說一下,平常我們都用git ci -m新建一個commit,其實通常我們不用新建commit,而是用git ci --amend追加的方式

這里我們修改了loading中的內容,然后git add -u 加入到緩存區,因為我們只是修改了很少的內容,不需要重新提交commit,所以使用git ci --amend追加到之前的commit,這時會讓我們修改注釋內容

這是一個vim的編輯器,之前linux中有講,按i進入編輯模式,箭頭移動光標就可以修改注釋,修改好后,按ESC進入一般模式,按:進入命令模式,輸入wq,保存退出

git log后發現沒有新建commit,只是追加到了之前的commit

我們在使用的過程中可能要回到某一個提交,這時可以使用git reset命令,這個命令可以帶參數,--mixed(回到修改未保存狀態),--soft(回到緩存區狀態),--hard(刪除所有修改),默認是--mixed

先講講--hard,這個好理解,就是把這個commit之后的所有修改都刪除

這里有四個commit

我們先使用git reset --hard ,將“我修改了名字”之后的所有修改的刪除

git st后發現,沒有任何修改

git log后,已經回到”我修改了名字”的commit

下面我們試試git reset --mixed或者git reset

git log我們會發現--mixed和--hard都回到了“我修改了名字”的版本,區別在于git st后--mixed將“測試reset1”和“測試reset2”中修改的內容保留下來了,這樣好處在于,我們有時回到某一個commit不是要刪除所有的修改,而是只想改變某一些東西,這時我們把需要改的地方改掉后,再重新提交一個commit,這樣會方便很多

最后我們試試git reset --soft

這個跟git reset --mixed差不多,只是它是把之后的修改放入了緩存區

三.分支操作

之前我們的操作都是同一個分支上的操作,現在我們引入分支的概念

  • 查看分支
git br

git默認都會有一個分支叫master,這個分支叫主分支,一般來說我們提交代碼的時候是用這個分支來提交,但是實質上它跟普通的分支沒有什么區別

為什么我們要引入分支,svn也有分支的概念,但是基本是在服務器端,我們本地基本是在一個分支上修改內容的,然后commit,有時我們改一個東西A可能需要很長時間,當還沒有改完卻突然要修改另外一個東西B,而且A因為沒有改完不能合并到版本庫,這時svn就有點乏力了,我們可能要把之前沒改完的東西A刪除掉,然后再來改接下來的B。

git因為是分布式的,不管是服務器端還是本地,都可以存在很多分支,這樣就方便我們利用分支很好地管理代碼,當我們修改任務A的時候,我們可以在分支A上修改,分支A在master的基礎上新建而來,當我們還沒有處理完A就要處理B時,我們可以新建另一個分支B,也是在master的基礎上新建而來,這樣當我們處理完B,提交后,可以回到A,繼續我們之前的開發,當我們開發完A,要提交的時候,我們把B的內容整合進來,這個涉及到分支合并,我們之后再講

  • 新建分支
git co -b TEST  //新建名為TEST的分支,當前的分支會以綠色顯示

當我們新建分支時,是從當前分支的基礎上新建的,新建的分支保留了當前分支所有的修改,所以新建分支相當于對當前分支的一份拷貝,而不是一個空的分支

  • 切換分支
git co master  //切換到master分支
  • 刪除分支
git br -D TEST //D大寫,表示強制刪除
  • 分支合并
    講合并,我們就回到之前那個例子,我們處理A任務和B任務都新建一個分支分別為TESTA和TESTB,這兩個分支都是在master的基礎上新建過來的

這里有三個分支,分別是master,TESTA,TESTB

主分支master有兩個提交

git co TESTA切換到TESTA,上面有三個提交,在master基礎上多了一個“測試A”的提交

git co TESTB切換到TESTB,上面有三個提交,在master基礎上多了一個“修改B”的提交

現在我們需要把A和B合并到一起

首先切換到TESTA分支,然后使用git rebase TESTB命令,將TESTB合并到TESTA前面

一般來說,如果兩個分支沒有沖突的話,合并就完成了,像上圖有沖突就需要解決沖突

git st后發現,TESTA和TESTB都修改了loading文件

git diff loading后,查看具體的沖突內容,git用特殊的符號標記沖突,<<<<<< HEAD到=======之前是你要合并的分支對當前文件的修改,因為現在我是要把TESTB合并到TESTA,所以HEAD就代表TESTB的修改,也就是“我是用來追加的B”是TESTB的修改,然后======與>>>>>>之前的內容是TESTA的修改,也就是“我是用來追加的A”這句話

現在我們要做的就是確認好是保留A的內容,還是保留B的內容,還是A和B的內容都保留,我們修改可以用linux的vim工具來修改,也可以直接在Android studio或者xcode中修改,修改時先將<<<<<,======這些特殊標記符號去掉,然后再進行修改

修改完成后,git add -u 將修改的內容加入到緩存區

然后git rebase --continue,繼續rebase操作

如果要放棄合并,使用git rebase --abort

合并完成后git log,我們可以看到,TESTB的修改“修改B”已經合并進TESTA了,這時TESTA分支中就包含了A和B的修改

四.與遠程服務器交互

  • 生成rsa密鑰
ssh-keygen -t rsa

查看id_rsa.pub文件,將密鑰拷貝到服務器密鑰庫

  • 從遠程復制倉庫
git clone 服務器倉庫地址

一般來說是新建一個空目錄,然后去克隆服務器的git倉庫

  • 在服務器添加倉庫

1.新建本地倉庫

git init

2.添加遠程倉庫地址

git remote add origin ssh://****@****:29418/foxleezh/test.git

3.提交遠程倉庫

git push origin master

4.切換到遠程分支

git br -r 查看遠程分支
git co 切換到某一個遠程分支

5.刪除遠程分支

git push origin :branch

6.拉取服務器分支并切換到臨時分支

git fetch origin branchname && git co FETCH_HEAD

如:
git fetch origin GIT && git co FETCH_HEAD

7.拉取服務器分支并合并到master

 git pull

pull命令相當于fetch命令加上merge命令,將服務器master分支的內容拉下來并合并到本地master

git pull --rebase

以rebase形式拉取,相當于fetch命令加上rebase命令

如果是pull其他分支,加上分支名

git pull origin branchA

8.向服務器提交分支

git push

如果是push其他分支,加上分支名

git pull origin branchA

9.常見錯誤

  • unable to rewind rpc post data - try increasing http.postBuffer
git config http.postBuffer 524288000
  • 高版本不支持ssl
Host www.xxx.com(改成服務器地址)
HostkeyAlgorithms ssh-dss

五.子模組

  • 新建子模組

1.新建父項目、子項目并上傳服務器
2.克隆父項目、子項目到不同目錄

git clone ssh://<username>@<hostname>:29418/project-1.git
git clone ssh://<username>@<hostname>:29418/lib1.git
git clone ssh://<username>@<hostname>:29418/lib2.git

3.將子項目變為父項目的子模組

git submodule add ssh://<username>@<hostname>:29418/lib1.git libs/lib1(這里目錄可以自由更改)
git submodule add ssh://<username>@<hostname>:29418/lib2.git libs/lib2

4.將父項目修改的修改提交服務器

git add -u
git push

至此,子模組新建完成

  • 修改子模組

1.進入子模組目錄提交并上傳

git add -u
git push

2.進入父項目提交并上傳

git add -u
git push
  • 克隆子模組

1.克隆父項目

git clone --recursive ssh://<username>@<hostname>:29418/project-1.git

2.切換子項目分支
到子目錄下(此時分支處于游離狀態)

git co -b newBranch
  • 更新子模組

1.在父目錄下更新

git pull
git submodule update

2.切換子項目分支
此時分支處于游離狀態

git co -b newBranch
  • 刪除子模塊(分4步走)

1.根據路徑刪除子模塊的記錄

$ git rm --cached [path]

2.編輯“.gitmodules”文件,將子模塊的相關配置節點刪除掉

清理子模塊配置

3.編輯“ .git/config”文件,將子模塊的相關配置節點刪除掉

清理子模塊配置

4.手動刪除子模塊殘留的目錄

清理臟文件

六、其他

  • Git找回commit
git reflog
  • 開發流程(以master為例)

    • 在master的基礎上新建一個分支進行修改
      git co -b newbranch
    • 在新的newbranch上改好代碼后commit
      git add -u

      git ci -m "newbranch的修改"
    • 切換到master上拉取最新代碼,防止別人上傳了代碼自己卻沒有更新
      git co master

      git pull origin master
    • 如果服務器有代碼更新,切換回newbranch合并服務器新增代碼(如果沒有更新,直接執行第5步)
      git co newbranch

      git rebase master
    • 切換到master,合并newbranch代碼
      git co master

      git rebase newbranch
    • 提交代碼到服務器
      git push origin master
  • 有關git rebase的常識

    • 對于rebase的順序

      比如 上例中newbranch和master兩個分支的合并

      一開始兩分支commit都是1,2,3

      后來newbranch提交了一個4,commit就是1,2,3,4的順序

      而master拉取服務器更新了5,commit就是1,2,3,5的順序

      這時我們切換到newbranch,去rebase master,即git rebase master

      rebase后的順序是1,2,3,5,4

      如果我們當初是切換到master,去rebase newbranch

      rebase后的順序是1,2,3,4,5

      這里的法則就是,去rebase哪個分支,就把哪個分支塞在下面
    • 對于rebase沖突的解決

      當我們rebase后,看見有沖突,git st后可以看到沖突的文件

      我們通過Android studio找到沖突的文件,去搜索=====或者<<<<<<這些特殊標記就會找到沖突的代碼

      修改沖突的代碼為你想要的代碼后,記得將=====,<<<<<這些特殊符號去掉

      修改好后git add -u,將修改的代碼提交到緩沖區

      git rebase --continue繼續rebase,這樣就將沖突解決了

      如果rebase過程中想取消,git rebase --abort
    • 能過rebase刪除某幾個commit

      比如newbranch上的commit為1,2,3,4

      這時我想將中間的2和3去掉,變為1,4

      我們首先要將2和3的commit號記下,比如是commit2,commit3

      然后git rebase --onto commit2空格commit3(commit2后面的是前一個的意思,這個符號在鍵盤的數字6上面)

      其實可以是git rebase --onto commit1空格commit3(因為commit2^就是commit1)
  • 一些Linux常用命令
    tab 補全命令

    ctrl+c 停止執行
    • 文件管理
      • pwd 打印當前目錄

      • cd 進入某個目錄
        cd /home/develop 進入絕對路徑

        cd eclipse 進入相對路徑

        cd ../ 返回上一級目錄

      • touch [file name]打開或創建一個文件

      • mkdir -p [dir name] 創建一個目錄 -p為強制創建

      • rm -r [file name/dir name] 刪除一個文件或目錄

      • ls -al 列出所有文件(包括隱藏文件)的詳細信息
        -d 只列出該目錄的信息

      • cp -rd [目標文件] [目的文件] 復制文件
        -r是允許目錄cp

        -d是在拷貝軟連接時只拷貝軟連接,如果不加則會把原文件一起拷過去

        cp -rd test.txt dir/test.txt

      • mv -i [目標文件] [目的文件] 移動文件
        -i是詢問是否覆蓋同名文件,如果[目標文件][目的文件]相同,那就是重命名

      • find [dn] [參數]
        如:find $HOME -name 'foxlee' -o -type f -o -size +20M

        -atime +n :訪問或執行時間大于n天的文件

        -ctime +n :寫入、更改inode屬性(例如更改所有者、權限或者連接)時間大于n天的文件

        -mtime +n :寫入時間大于n天的文件

        文件的 Access time,atime 是在讀取文件或者執行文件時更改的。

        文件的 Modified time,mtime 是在寫入文件時隨文件內容的更改而更改的。

        文件的 Create time,ctime 是在寫入文件、更改所有者、權限或鏈接設置時隨 Inode 的內容更改而更改的。

        因此,更改文件的內容即會更改 mtime 和 ctime,

        但是文件的 ctime 可能會在 mtime
        未發生任何變化時更改,例如,更改了文件的權限,但是文件內容沒有變化。

        這里講一下ls中顯示的時間

        ls -lc filename 列出文件的 ctime

        ls -lu filename 列出文件的 atime

        ls -l filename 列出文件的 mtime

        繼續講find的參數

        -name 'filename' 直接查找該文件名的文件(注意加引號)

        -type type :通過文件類型查找 type 包含了 f, b, c, d, l, s 等等

        d 表示該文件為目錄;

        f 表示該文件為普通文件;

        b 表示該文件為塊設備文件,比如磁盤分區

        l 表示該文件為連接文件(linux file),上邊提到的軟連接即為該類型;

        c 表示該文件為串行端口設備,例如鍵盤、鼠標。

        s 表示該文件為套接字文件(socket),用于進程間通信。

    • 文件查看與編輯
      • vim [fn] 編輯文件 有三種模式(一般模式,編輯模式,命令模式),可以自由切換

        一般模式下移動光標(esc回到一般模式)

        箭頭上下左右

      • 一般模式下查找與替換
        /word 向光標之后尋找一個字符串名為word的字符串,當找到第一個word后,按”n”繼續搜后一個,"N"前一個

      • 一般模式下刪除、復制粘貼
        dd 刪除光標所在的那一行

        yy 復制光標所在的那行

        p,P p復制的數據從光標下一行粘貼,P則從光標上一行粘貼

        u 還原過去的操作

      • 進入編輯模式(按i進入)
        i 在當前字符前插入字符

      • 命令模式(按:進入)
        :q! 不管編輯或未編輯都不保存退出

        :wq 保存,退出

        :e! 將文檔還原成最原始狀態

        :set nu 在每行的行首顯示行號

        :set nonu 取消行號

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • git常用命令 GIT常用命令備忘:http://stormzhang.com/git/2014/01/27/gi...
    新篇章閱讀 8,648評論 1 26
  • 對于運營人員來說,現在的工作越分越細。在經過行業大牛和運營高手們的不斷完善和總結后,如今的運營工作籠統的可分為三大...
    諸葛io閱讀 4,941評論 1 11
  • 搞錯了,身體需要原料 人體的修復能力是不是非常的神奇?可以說是無所不能,人體內的一切損傷都能通過修復而治愈,而且速...
    璀璨星空888閱讀 633評論 0 1
  • 不信任自己的人,連努力的價值都沒有。
    起風了雯雯閱讀 196評論 0 0