適合小白/外行的git與github最基礎最淺顯教程

首先聲明,這是適合小白/外行/初學者/學生看的最基礎最簡單的git與github教程,已經能使用svn,git等工具的朋友請不要看這篇文章來浪費時間了。

想進一步學習git的,推薦去廖雪峯博客學習。java

這是以前幫助幾個外行的朋友寫的最基礎git教程,僅讓他們理解基本概念,可以簡單使用。固然教程寫的也算用心,因此就從新整理一下放到博客上了。(其實主要是由於這段太忙了,沒時間寫新文章了,寫一篇好的文章真的太耗費心血了。因此手頭正好有一篇以前寫的教程就整理一下發表吧)。指望能讓小白/外行/初學者/學生能理解版本控制工具的基本概念與使用。python

這篇教程共計一萬八千字,花了個人不少時間精力,不過最後有人依舊沒學會,不得不說,這真的是一個很悲傷的故事。linux

文章概要總結

必須記住的六條命令。

  • cd:用來切換工做目錄,最經常使用的一個命令。簡單來說,cd A文件夾就是進入到A文件夾裏面的意思。
  • git status .:查看當前路徑下的的狀態。git下最最經常使用的一個命令。
  • git add .: 把工做區的全部變化,(就是你的全部改動),都添加到 版本庫/暫存區。
  • git commit -m "提交時說明信息": 更進一步提交,並說明提交log。
  • git push: 把版本庫的全部更新內容, 都推送到遠程服務器。(就是推代碼/推上去)
  • git pull: 把代碼從遠程服務器拉取到本地。(俗稱拉代碼)

當咱們修改了本地代碼,向遠程服務器推送時,咱們的操做步驟以下:git

  1. git add .
  2. git commit -m "提交時說明信息"
  3. git push
    當咱們想更新本地代碼,就是把服務器上最新的代碼拉取下來,只須要執行一個命令。
    git pull

這三條命令建議記住。

  • git log:查看提交歷史,與各次的提交說明。
  • git diff:比較工做區與暫存區的差別,就是比較看看你到底都作了什麼修改。
  • git clone url地址: 將遠程服務器上項目克隆到新建立的目錄中(第一次拉項目時使用, 後面的更新都用 git pull了)。

其餘問題

  • 操做時 雙擊tab鍵的自動提示/補全功能。
  • q或者:q等命令表明退出(quit)。
  • ctrl+f,ctrl+b快捷鍵在termial能夠翻頁,就是 上一頁,下一頁

最重要的內容再強調一遍:

這是給小白/外行/初學者/學生看的最基礎最簡單的git與github教程,已經能使用svn,git等工具的朋友就不要看這篇文章來浪費時間了。

另外,這篇文章也不是講述git安裝的,或者github帳戶建立,key上傳的。相似的文章網上遍地都是,本身去搜索吧。程序員

文章正文

git是一個分佈式版本控制系統。簡單來說,若是有幾我的同時開發維護一個項目的代碼,那麼咱們就找個中央服務器,放置一份公共的代碼,每一個人在各自的電腦上去修改各自的代碼,而後修改完,提交到中央服務器。這樣你們拉代碼時,就能更新到其餘人修改的內容了。。github

Notice:代碼只是爲了便於說明。版本控制系統,管理的是文件,因此任何文件均可以。圖片啦,視頻文件啦,二進制文件啦,沒有什麼不能夠的。只是咱們爲了行文方便,直接說代碼文件。編程

本教程會講述 命令行 操做。不過也有不少人 使用圖形化界面軟件 好比source tree或者 俗稱的小烏龜軟件 來操做。可是基底的原理是同樣的。source tree 軟件操做也只是命令行的 封裝。而且圖形化操做更加直觀一些。熟悉了命令行,圖形化軟件操做天然也會。不會命令行,圖形化軟件操做也能夠會,可是會理解的比較膚淺。更重要的是會了其中一個,學習另外一個就很是容易了。vim

本篇文章之因此採用 終端(termial)命令行的方式,除了我本人平時一直使用命令行操做以外,還有重要的一點,命令行具備更普遍的適用性。換句話說,你熟悉了 git的命令行,那麼利用命令行進行其餘操做,好比java,python,運行測試腳本等,對你來講很easy,理解了最底層的原理,學習圖形化軟件也會很容易,畢竟圖形化軟件那麼多,你永遠學不完的,可是理解了底層的,就能以不變應萬變。api

理解幾個概念

工做區(Working Directory), 版本庫(Repository)/暫存區 ,(中央/遠程)服務器.服務器

  • 服務器的概念已經清楚了。叫作 中央服務器/遠程服務器都行。
  • 工做區:就是你電腦的工做目錄
  • 版本庫:工做區有一個隱藏的 .git文件夾,這個是叫作 版本庫(有些文章也叫 暫存區,無論叫什麼,知道這個意思就好)。.git 是隱藏文件夾。該文件內的內容很重要,由於git的控制配置等信息,都在這個隱藏文件夾裏。電腦若是設置不顯示隱藏文件夾,那麼就會看不到。

我電腦上的一個項目,能夠看到什麼是工做區,暫存區.

圖片名稱:工做區與暫存區.png

工做區與暫存區.png-65.6kB

爲何存在一個 版本庫

我修改過的代碼,直接從 工做區提交到服務器不就好了嘛,爲何還要這麼麻煩。svn 等集中式版本管理系統就是這麼作的,簡單明瞭,可是若是你沒網絡時怎麼辦?因此有了 版本庫,那麼你能夠把代碼先從工做區提交到版本庫,等待有網絡了,能夠再提交到服務器。

.gitignore文件是幹啥的?

工做區的目錄下面,總會存在不少亂七八糟的文件,好比你本地的配置,編譯生成的中間文件等,這些文件你不想(或不能)提交到 服務器。那怎麼辦呢。就把這些文件的規則寫到 .gitignore文件中,這樣git就會 ignore(忽略)這些文件,git就會像沒看到這些文件同樣。

好比個人.gitignore文件有些內容以下:

git忽略文件.png-3.6kB

這幾句話的意思是 全部apk後綴的文件,class後綴的文件都忽略,bin/gen/目錄下的文件也忽略。說的通俗一點,就是你git別管這些文件了,這些和git沒屁關係。我無論怎麼倒騰這些文件,都和git不要緊。另外, .gitignore 文件中,#號開頭的行 表明註釋,就像 編程文件中的//開頭的行同樣。

幾個簡單的命令。

怎麼建立一個被git控制的項目,後面再講,這裏先講述幾個基本命令。

在此以前,先熟悉一個 cd命令。

cd命令用來切換工做目錄,linux,mac環境下最經常使用的一個命令。 簡單來說,cd A文件夾就是進入到A文件夾裏面的意思。好比我要進入d盤個人代碼文件夾, 輸入命令 cd /d/code/github_blog/而後回車。

假設你在一個項目中修改了某些文件。

你想看看當前目錄下是什麼狀態,命令 git status .

. : 一個點表明當前目錄,..:兩個點 表明上級目錄。 (這和git無關,這是 計算機基本的常識)。那麼請思考,cd ..,這個命令是啥意思?

可是你敲命令的時候,記不清楚了,或者 打錯了了。看看termial會有什麼反應?

$ git satds
git: 'satds' is not a git command. See 'git --help'.

Did you mean this?
        status

有不少的概念和操做,都和什麼git無關,都是計算機領域中的基本常識,或者 全部(至少絕大部分)軟件都遵循的操做常識,git天然也一樣遵循這樣概念和操做,這些內容我會用斜體的 計算機常識 來標註。

$ git satds一行,$ 表明的是命令行的開始,後面的內容表明的就是你的輸入內容。而 它的下一行就是系統反饋/迴應 你的內容。(或者說系統輸出)。(計算機常識)

你看到什麼?git會問你, 它不認識這個命令啊,你是否是敲錯了,你能夠用git --help尋求幫助哦。另外你是否是想打 status 這個詞呢? 因此git的命令根本 不用背,有個簡單的印象就好。

甚至,你在敲打命令的時候,根本不用敲完,輸入頭幾個字符,而後直接 敲擊 tab鍵,看看會發生什麼?

$ git sta //敲擊 tab
stage    stash    status

系統直接提示你了,sta開頭的命令有三個,就看你想用哪一個了,這是爲了你記憶。
而你敲擊 git stat以後,再敲擊 tab,再看看 會發生什麼。由於此時 stat開頭的命令只剩下一個了status,因此你也只能打這個命令了。因此git自動幫你補全了。。

點擊tab鍵的 自動提示/補全功能頗有用,絕大部分命令行操做都有這個快捷鍵,畢竟那麼長的命令,文件路徑等,記憶很難,打字也很累。不過有些termial狀況,是點擊一次tab鍵,而有些則是雙擊tab鍵,反正你能夠老是雙擊tab鍵,這總不會錯。(計算機常識)

費了好大勁,咱們終於輸入了正確的字符。看看 命令行 會輸出什麼內容。

圖片名稱:git_status.png

git_status.png-11.5kB

我在測試前,作了如下幾件事情:

  • 新創建一個 test0908.txt 文件。
  • CachedThreadPool.java 文件中修改了一些內容。
  • 刪除了 DirectThread文件。

而後你看看 git 輸出的內容。咱們逐行進行分析。

On branch master
Your branch is up-to-date with 'origin/master'.

第一行不用管,這是 分支(branch)的概念,基礎教程不涉及分支。(想進一步學習了去廖雪峯的博客)
第二行:你的分支與遠程分支已經同步了。(就是遠程服務器並不比你的代碼新)

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)

        modified:   java/src/thread_runnable/CachedThreadPool.java
        deleted:    java/src/thread_runnable/DirectThread.java

翻譯一下:

改變尚未到提交階段呢。
(使用   `git add <file>...`  命令 來更新 你的提交。)
(使用 `git checkout -- <file>...`命令來放棄你工做區的修改 )
 而後下面 列出了你修改的具體文件。
 `modified`表明修改,`deleted`表明 刪除。(還有add表示增長,像svn中就直接簡寫M,D,A了,若是若是看到了這些簡寫了,要明白什麼意思)

提示內容已經很是明明白白的告訴你了,你的修改內容,以及你下一步能夠怎麼作了。
你能夠 使用git add命令來提交;也可使用 git checkout 來放棄修改。(就是 把工做區從新變乾淨,把你修改的東西都恢復了,就像 ctrl+z同樣)。

而後還有幾行:

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

        test0908.txt

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

翻譯以下:

未跟蹤的文件
(使用 `git add <file>...` 命令會包括下面這些提交)
  你添加的文件名
 如今還沒走到commit地步呢。(可使用 `git add` 或者  `git commit -a`)

首先 test0908.txt爲何是 Untracked files,由於我剛纔就說了,個人這個文件是 新添加的,git以前沒見過這個文件(git剛剛第一次見到這個文件,因此感受很面生,不認識啊)。因此它說這個文件未跟蹤,而上面那兩個文件 CachedThreadPool.javaDirectThread.java這兩個文件,由於以前早就添加了,因此git系統會認識這兩個文件。

那麼如今工做區就是這個樣子了。

我想看看我具體到某個文件進行了什麼修改。該怎麼操做呢。
git diff 操做。

git_diff.png-38kB

這個內容顯示的有些亂七八糟。

首先你看到 它列出了第一個文件
diff --git a/java/src/thread_runnable/CachedThreadPool.java b/java/src/thread_runnable/CachedThreadPool.java
前面一個a,後面一個b,其實就是表明你修改先後的文件。(不用關心這些)。
而後下面,是具體內容,

  • 全部 + 開頭的,表明的都是你添加的內容,
  • 全部 -開頭的,表明的都是你刪除的內容。
  • 那些既沒有"+"也沒有"-"開頭的行,就是和你修改區域的相關上下文,有了這些上下文,能夠更好的幫你回想起來,你到底都修改了什麼了。

而且它們顯示的顏色也不一樣。

而後它列出了你修改的的第二個文件。

diff --git a/java/src/thread_runnable/DirectThread.java b/java/src/thread_runnable/DirectThread.java
deleted file mode 100644

它也提示你了,你把這個文件刪除了。
而具體的提示,則所有是紅色的 -號區域。爲何是所有是 -號區域,由於你把這個文件都刪除了,那天然是至關於你把全部的內容都刪除了。

爲何 你添加的 test0908.txt 文件沒有被這個命令提示,由於 這個文件尚未被跟蹤,再說,也不必顯示啊。由於這個文件的全部內容 都是你新添加的。

我把termial的界面調整到最大了。因此能夠所有輸出,若是文件改動不少/termial界面過小,一屏幕輸出不完。那麼 ctrl+f,ctrl+b快捷鍵分別顯示 上一頁,下一頁,q或者:q等命令表明退出(quit)。(計算機常識)

上面雖然解釋了git diff 命令的意思。可是這個顯示的確讓人眼花繚亂。而 source tree等圖形化工具,關於這個對比顯示,的確直觀了不少。

圖形化界面是相似下面這樣顯示的,看着 直觀了許多。

圖片名稱:git_diff_圖形化界面.png

git_diff_圖形化界面.png-113.8kB

(其實eclipse等IDE,都附帶了相似的工具幫助你比較你都修改了什麼,顯示結果用圖形化界面形式來顯示,比較直觀,不過這裏就不作具體說明了。可是git diff的確比較少用,由於這種termial輸出看的眼睛都花了)

咱們 已經知道了工做區的狀態,也知道修改了哪些內容。
那麼下面該作什麼呢。

git status .時,已經很清楚的提示下一步命令是什麼了。

咱們先把文件從 工做區提交到 版本庫。
本次提交時,你能夠只添加某一個文件,其餘文件你沒修完還不想提交呢: git add java/src/thread_runnable/CachedThreadPool.java
也能夠 一次提交兩個文件(文件中間空格分割): git add java/src/thread_runnable/CachedThreadPool.java test0908.txt
你固然也能夠一塊兒提交全部的修改。git add .(通常經常使用的就是這個命令,修改了就所有添加,省的麻煩)

思考一下最後一個命令爲何是這樣,不要忘記一個點.表明什麼。
更別忘記了剛纔強調的tab快捷鍵, 不然那麼長的文件路徑打字累不累啊。(固然,你複製粘貼也能夠的)

好。咱們把 全部文件提交了,
$ git add .

這一步沒有沒有任何輸出。

此時 git status .看看 什麼狀態。

圖片名稱:git_status_after_add.png
git_status_after_add.png-19.4kB

提示區域已經告訴咱們了能夠怎麼作了。

你可使用 `git reset HEAD <file>...` 來恢復上一步操做。

這裏提示了怎麼進行恢復。而上面那句話是啥?你能夠進行committed啊,(固然,git直接提示使用git commit進行更進一步的提交才完美。)
而後 我執行 下面命令,進行更進一步的提交操做。

git commit -m "我這只是一次提交測試,進行教學的提交測試"

命令的 -m "提交說明" 是添加說明的。

此時你的代碼改動都已經放到了 版本庫了。

而後再 git status .,看看提示了什麼:

圖片名稱:git_status_after_commit.png
git_status_after_commit.png-25.5kB

下面幾句話值得注意:

Your branch is ahead of 'origin/master' by 1 commit.
  (use "git push" to publish your local commits)
nothing to commit, working directory clean

origin是原點,遠程的意思。因此這句話是這個意思。

你能夠 使用 `git push` 來向遠程 發佈你的 變化。(其實就是推送到遠程服務器>)

那麼咱們就 git push吧。。把 版本庫的東西,推送到遠程服務器。由於你寫了代碼,原本就是爲了提交到遠程服務器嘛。。

咱們來看看 git push以後,提示了什麼。

圖片名稱:git_push .png
git_push .png-30.6kB

此次操做輸出的內容也是讓人眼花繚亂,上面的那一部分一樣是相關提示,告訴咱們可使用更詳細的命令,這個區域不用管。我也沒研究過什麼內容,關注一下我紅框畫出來的內容。

其實在輸入git push命令時,輸出會停留在下面這一行,等待你輸入密碼。

Enter passphrase for key '/c/Users/Administrator/.ssh/id_rsa':

這個是咱們在最初設置git環境時,設置的ssh密碼,好比個人電腦上設置的是 123456。輸入了密碼,而後才能輸出下面那些內容,表明此時咱們的操做已經完成了。

有些人的電腦上,使用 git push時, 並無輸入密碼這一步驟,那是由於他們在最初配置git環境時,把密碼這步省略了(或者記住了密碼),因此他們不用輸入密碼。

下面這幾句內容。

Counting objects: 7, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (5/5), done.
Writing objects: 100% (7/7), 671 bytes | 0 bytes/s, done.
Total 7 (delta 4), reused 0 (delta 0)

是一些push時的 提示內容,沒必要關心(反正我也看不懂)。。
再下面兩句。

To git@git.oschina.net:yaowen369/ConcurrentDemo.git
   5c53c8f..0e522fe  master -> master

To 表明的意思是目的地,你本地提交到了哪裏?由於個人這個項目放在了 oschina 託管網站上了,(oschina地址:http://git.oschina.net/) 因此就是說,個人代碼被提交到了 那個地址了。 本地master分支到 遠程master分支。

oschina和github同樣,都是代碼託管網站。(固然,你託管其餘文件天然也能夠)。相似的網站有不少,還有gitlab之類的, 不過github最有名罷了。 所謂託管,意思就是至關於他們提供了一個遠程服務器,供你放置你的文件。這個問題下面的內容會講到。

到了這個步驟,咱們修改的內容,都已經被提交到了遠程服務器上,雖然有時候敲擊命令時,termial提示了咱們不少亂七八糟看不懂的內容,可是這不重要,看不懂也很正常,徹底看懂也不必,由於咱們的目的已經達到了,就是 把本地修改 提交到了 遠程服務器上了。

此時咱們再使用 git status,看看當前狀態是什麼。

圖片名稱:git_status_after_pull.png
git_status_after_pull.png-14.9kB

上面的意思是說

你當前的分支已經和`origin/master`同樣新了(就是內容一致了)。
沒有什麼東西要提交,你的工做區很乾淨。

此時,我打開了個人mac電腦,個人mac電腦上也有這個項目。我有時候在公司電腦上寫代碼,有時候在本身的mac電腦上寫代碼,因此有了git,均可以方便的在不一樣電腦上切換。

我在本身的mac電腦上,進入到對應的代碼目錄,使用了 git pull命令,看看什麼反應。

有些時候,也會要求你輸入ssh的命令,才能拉代碼,直接輸入以前設置的123456密碼就好了。

圖片名稱:git_pull.png-
git_pull.png-149.1kB

最上面的那幾句話不用看(我也看不懂,也徹底沒看懂的必要)。
只看最重要的部分

From https://git.oschina.net/yaowen369/ConcurrentDemo 

   5c53c8f..0e522fe  master     -> origin/master
Updating 5c53c8f..0e522fe
Fast-forward
 java/src/thread_runnable/CachedThreadPool.java |  5 ++++-
 java/src/thread_runnable/DirectThread.java     | 24 ------------------------
 test0908.txt                                   |  1 +

這個文件從 oschina遠程服務器拉下來了,而且此次 拉取 更新了那些文件呢。。就是下面三個。

java/src/thread_runnable/CachedThreadPool.java |  5 ++++-
 java/src/thread_runnable/DirectThread.java     | 24 ------------------------
 test0908.txt                                   |  1 +

這不就是我在本身辦公電腦上修改的那三個文件嗎?而且看到後面的 +,- 符號,它還告訴你了,有些咱們添加內容了,有些咱們刪除內容了。因此到了這個時候,
咱們經過status,add,commitpush,pull這五個簡單的命令,咱們就能簡單的使用 git了。。這已經能知足咱們平常80%的需求了。(對於一我的開發的項目,而不是 團隊多人開發模式來說,這五個命令已經能知足95%的平常需求了)

至於有些命令的提示輸出內容等,看不懂就看不懂了,都看懂又有啥用。咱們只要會用就能夠了。好比 git push命令以後,termial提示輸出了那麼多的內容,你只要簡單的能看懂,咱們推送成功(仍是失敗)了這就ok了。其餘的不用管。

衝突問題

但是人生哪有到處都如意的時候呢,代碼也是如此。若是A和B都同時修改了同一個文件會發生什麼呢,此時就會發生衝突。

好比張三修改了 A.java文件上傳到了中央服務器,而後李四在本地也修改了 A.java文件,李四想提交文件時,會提示由於衝突而沒法提交。系統要求你先把代碼拉下來,合併了A.java的衝突(這個合併過程,其實有時候git會自動合併,可是複雜的合併git作不了,因此就要求李四本身去合併衝突),而後李四才能提交上去。。。

固然,你工做電腦上提交,而後 本身私人筆記本上又修改了同一個文件,這和上面是一樣的意思,只是 咱們用張三李四來方便表達。

因此爲了不潛在衝突一個好習慣就是 你在修改你的代碼以前,先git pull一下,把服務器的最新代碼拉下來,這是一個好習慣。

所以咱們開發時,有時候早晨來了第一件事情,就是先把代碼git pull一下,進行更新。這是個好的開發習慣。避免你寫了不少代碼,你同事也寫了不少代碼,而後衝突了,大家倆合併的時候,比較浪費時間。

我如今就實際作一個衝突的demo,演示衝突是怎麼發生的,又怎麼解決。其實都很好解決。。

我在本身的mac電腦上修改了 FixedThreadPool.java文件,而後 在mac電腦上 操做了 add,commit,push操做,提交到了遠程服務器上。

而同時,我在本身的工做電腦上, 也對 FixedThreadPool.java文件 進行了修改。而後我在本身的工做電腦上, 執行了add,commit操做,如今我要提交了,我執行了 push操做,看看會發生什麼。

圖片名稱:git_push_error_because_confilt.png
git_push_error_because_confilt.png-63.2kB

此時再看看對方 termial提示了什麼。輸出了一大串內容,前面的內容不用關心。
咱們只看最後一段主要內容。

To git@git.oschina.net:yaowen369/ConcurrentDemo.git
 ! [rejected]        master -> master (fetch first)
error: failed to push some refs to 'git@git.oschina.net:yaowen369/ConcurrentDemo.git'
hint: Updates were rejected because the remote contains work that you do
hint: not have locally. This is usually caused by another repository pushing
hint: to the same ref. You may want to first integrate the remote changes
hint: (e.g., 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.

翻譯其中的主要內容:

! [拒絕]        master -> master (fetch first)
錯誤:向'git@git.oschina.net:yaowen369/ConcurrentDemo.git'執行 `push`時,發生了某些錯誤。
提示:更新之因此被拒絕是由於 遠程分支包含了你本地沒有的內容,這一般是由於 另外一個庫推送了一樣的文件(ref是索引的意思,能夠翻譯成文件)。你能夠在推送以前先合併這些遠程的變化(好比,試試 git pull)。

你能夠看看 `git push --help`中的 `Note about fast-forwards`瞭解更多的細節。

其實在命令行中,help是頗有用的,能夠提示不少有用的幫助信息,不過有些termial要求直接 命令後面輸入 help就行了,有些要求輸入 -help,有些要求輸入 --help,或者有些直接輸入 -h/--h也行,可是咱們始終要有這個意識,由於太多東西不用記憶,有個大概的印象就好。(計算機常識)

看到這些提示內容,即便你第一次碰到這個問題,你下一步準備怎麼作?人家已經給你提示了啊。直接 git pull啊。

Notice:在你輸入 git pull時,有時候termial會要求你輸入密碼,有時候不會,可是 很快的,termial就會徹底的跳轉到一個新的頁面,這應該是你第一個碰到這種狀況。

圖片名稱:git_pull_confilit_vi.png
git_pull_confilit_vi.png-35kB

這實際上是個vi編輯器,(vimvi的升級版,由於vim顏色高亮作的比較好,看起來更舒服)。
咱們在以前執行 git commit -m "相關提交的log內容"這個命令時, 直接輸入 一行提交說明內容,因此沒那麼複雜,咱們就寫一句話 說明一下而已(搞那麼複雜幹啥子)。可是你若是執行 git commit, 不帶-m 而後你直接敲擊回車,也會進入這個vi頁面。(由於你沒使用一行的提交說明模式,系統會覺得你想長篇大論的去寫提交信息呢,因此專門給你準備個編譯器,你好好寫吧,想寫多少,就寫多少)

說簡單點,vi和你的word,notepad,sublime text沒啥區別,包括和你電腦上新建個 文本文檔,都是一回事, 都只是一個文本編譯器, 可是這個 vi的歷史可比後面的那幾個歷史早太多了,上世紀八十年代,電腦圖形化界面還沒發明呢,當時電腦操做都是黑乎乎的命令行窗口操做(其實如今window,linux也能夠直接黑乎乎的termial操做,只是那麼多命令,你們都記不住,有了鼠標和圖形化界面,黑乎乎的命令行操做都被忘記了,只剩下程序員使用termial了)。word 等更無從談起,可是你們不少時候也要 編譯文本啊,又沒有word等,因此vi就是一個當時環境下的 termial環境操做的 文本編譯器,徹底 鍵盤操做,有無數複雜的 快捷鍵,你使用vi操做,徹底不用接觸鼠標,因此操做也比較快(固然是在你比較熟悉快捷鍵的狀況下,不然你就尷尬了)。

咱們這裏呢,不討論vi。vi的操做是另外一個話題。(其實也不是難,而是那麼多複雜的快捷鍵組記憶着比較困難而已)。

咱們能夠看看 它上面的內容說了什麼。

Please enter a commit message to explain why this merge is necessary, 

Lines starting with '#' will be ignored

翻譯內容:

請輸入一些提交內容來解釋爲何此次合併是必須的。
以`#`號開頭的行都會被忽略(註釋的做用)

其實上面那句Merge branch 'master' of git.oschina.net:yaowen369/ConcurrentDemo,就是它默認幫你生成的 提交信息。
反正你不用管(由於你要搞定這個,這是另外一個學習內容,可是你學習這些徹底不必,雖然也不難。這也是source tree等軟件的好處,使用了 source tree等圖形化軟件,你怎麼着也不會碰到vi界面),還記得 怎麼退出不?

輸入:q, 字符q表明是退出(quit)的意思,不過這個 vi的退出要 一個冒號+q,因此你輸入 :q,直接退出就行了。(git有些界面退出也是:q,只是你輸入命令操做的時候,git自動幫你前綴一個冒號了,因此給你省事了而已)

你輸入 :q,注意左下角。

vi_q.png-60.2kB

vi當中: 開頭的都是命令模式,命令模式顯示都在左下角。你輸入 :q回車後, 左下角出現了這麼一行紅色的文字。

E37: No write since last change (add ! to override)

你輸入:q居然沒用,相關區域提示你,由於這個文件你啥都沒改動,因此你要加個!號去覆蓋(其實就是強制退出模式)。 而後你直接輸入 :q!就行了。(直接輸入:號就行了,那行紅色的提示就消失了,而後你接着輸入q!就行了,你試圖用鍵盤上的delte等按鍵去刪除紅色文字沒用的)

還要討論vi的相關內容。可是不討論用戶十有八九又會碰到這個問題,當年我第一次碰到vi問題,連怎麼退出都搞不定,急的滿頭大汗。因此不得不討論。

終於咱們退出了 vi,看看具體提示了什麼。。

confilit_after_vi.png-29.1kB

紅色方框內的內容不要管,那是由於我第一次在vi中輸入命令 時,輸錯了 :!q,因此vi提示 q命令找不到,我又從新進入輸入了 :q!,就ok了。。

咱們看重點內容:

Auto-merging java/src/thread_runnable/FixedThreadPool.java

Merge made by the 'recursive' strategy.
 java/src/thread_runnable/FixedThreadPool.java | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

注意:Auto-merging自動合併了。也就是說, 由於我剛纔測試的衝突比較簡單,因此 git自動比較合併了。(好比張三修改了文件的第一行,李四修改了文件的最後一行,這種簡單的,git就能自動合併,可是張三李四都修改了 文件的第一行,那就只能手動合併了)。

那麼此時你使用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)
nothing to commit, working directory clean

你的工做區很乾淨,沒啥可commit的,可是 注意上面那句話
Your branch is ahead of 'origin/master' by 2 commits.
你當前的分支領先 遠程分支 兩次提交。

爲啥是兩次,由於原本你就commit了一次,而後 git pull時,又自動合併commit一次,因此就兩次了。

不用關心幾回,看到重點就對了,你當前的分支領先遠程分支。
另外,扯了這麼大一段,別忘記了最初我們的目的是什麼,我們最初的目標就是 推送代碼到遠程服務器。

因此接下來直接 git push,將 代碼直接推送到遠程服務器就行了。

此次的衝突由於我製造的比較簡單,因此自動合併了,可是有些衝突比較複雜,git沒法自動合併,
那麼此時就須要你手動合併了。

下面的demo直接借用了網上別人的代碼衝突內容 ,我針對輸出進行解釋。

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

系統提示你,test.txt文件衝突了,自動合併失敗了,你須要解決衝突,而後並提交。。

好,我打開test.txt文件,會看到下面的狀況。

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

其中衝突的部分都是用 <<<<<<<=======>>>>>>>來進行標記了,他們都表明了不一樣分支(或者遠程/本地)不一樣的內容,你本身看着代碼,把<<<<<<<=======>>>>>>>進行刪除,該刪除的代碼部分也進行刪除。

若是是你本身寫的代碼,你確定知道該刪除那些內容,若是不是你寫的代碼,好比李四寫的,那麼你要叫着李四討論,把大家兩個的代碼合併掉。李四寫的代碼你又不瞭解業務邏輯,你不和他討論, 就瞎合併,這在多人團隊中,是大忌。

由於你可能把李四寫的代碼給覆蓋掉。而程序員基本上寫完某個文件就再也不關心了,因此李四也不知道你把他的內容覆蓋掉了,這確定會引發問題,若是測試人員能發現業務邏輯不對,那還好,最多被測試人員提個代碼臭罵一頓,但若是測試不能發現,那等着線上事故吧。

好比上面的那段衝突,咱們合併成以下形式,並進行文件保存。

Creating a new branch is quick and simple.

合併以後,至關於你又從新 修改了文件。
因此在此從新進行提交步驟。。

$ git add readme.txt 
$ git commit -m "老子把衝突合併了"
[master 59bc1cb] 老子把衝突合併了

最後再push就行了。。

到了這裏咱們就理解了平時的提交代碼,拉取代碼的步驟,以及怎麼解決衝突。
咱們再來學習一個命令。git log

git log: 查看以前每次提交的說明信息:

git_log.png-78kB

直接看輸出應該一目瞭然了。每次提交的版本號。做者,時間,提交的信息說明 都直接列出來了。我們以前在 git commit -m "說明信息",這裏就有用了,不然那麼屢次提交,誰也沒本事都記住啊。

尤爲是你注意最上面那個 說明信息:

commit fb095209cc6adf53a98035cc7661d109a2024de9
Merge: 5b90fa3 c63c40b
Author: yaowen <yw43194@ly.com>
Date:   Sat Sep 9 11:45:40 2017 +0800

    Merge branch 'master' of git.oschina.net:yaowen369/ConcurrentDemo

最上面的是 版本號(就是那一長串奇怪的字符串),git的版本號是一長串字符串,而svn的版本號就是很簡單的1,2 ,3, 4阿拉伯數字,簡單來說,由於svn你每次提交拉取時,都是直接與中央服務器交互,而git則是先與版本庫(暫存區)交互,多人都使用git來提交代碼,他們本地的電腦時間都不必定準確,不能使用1, 2, 3,4做爲版本號,由於不能簡單的依據時間戳來比較。而svn則能夠直接使用服務器時間。

此次提交信息,還很貼心的給你提示了,你此次提交實際上是一個 合併衝突操做merge,而且提交的說明信息Merge branch 'master' of git.oschina.net:yaowen369/ConcurrentDemo,就是剛纔合併時系統幫咱們生成的。(由於當時咱們在vi界面並無修改默認的提交說明信息啊)。

注意右下角的冒號, 由於我這個項目提交不少次了,因此log說明比較多,一頁顯示不完,你還記得怎麼上下翻頁,怎麼退出log提示不?(翻頁通常用不到,由於咱們通常看提交log也都是看最近的幾回說明,不過怎麼退出這確定是要知道額)

那麼下面咱們要討論怎麼結合github使用。

github

咱們爲何要使用github,由於咱們須要一個遠程服務器啊。

在本文最初的時候,就說了須要一個遠程服務器,咱們上面那麼多的操做,都是客服端的操做。都是假設咱們已經搭建好了遠程服務器,而在公司裏,也已經搭建好了代碼服務器,因此咱們平時的代碼等都是發佈到那裏的,可是單獨的我的的小項目,你代碼託管到哪裏呢?固然,你能夠用本身的電腦搭建個git服務器,可是這是一個很是複雜的過程。因此咱們就能夠託管到github上之類的,這樣不就給咱們省了不少事情嗎?反正又不要錢,對吧。

github帳號的建立,ssh key的上傳本身去google搜索吧,咱們就直接來建立一個項目..

圖片名字:github_new_repository.png

github_new_repository.png-65kB

注意那個箭頭,點擊加號, New repository, 這就是建立一個新項目的意思。

圖片名稱:github_create_new_repository.png
github_create_new_repository.png-53.3kB

關於這個界面:

  • Repository name: 項目的名字,我此次的項目就叫作 TeachDemo(這個名字後面會說明,和你eclipse的項目名字保持一致最好)。
  • Description (optional),描述(可選),這個不用多介紹了。
  • 咱們只能建立Public,由於 private是要money的。(不過oschina上你能夠免費建立私有項目,你能夠建立個項目,放你的一些電子書之類的不那麼隱私的資料)。
  • Initialize this repository with a README,是否初始化一個 readme文件,是markdown格式的, 建議 勾選吧。
  • Add .gitigonre:這時候再說看不懂這欄啥意思,那就說明以前的文章都白寫了。既然你寫java代碼,那就選擇個java的。
  • Add a license:這個不用管。

此時咱們填寫和勾選都已經完畢了, 點擊藍色確認按鈕吧 Create repository,
此時進入了這個頁面。

github_teachDemo_ok.png-60kB
此時該項目建立ok了。。。你會看到項目當中給你初始化了兩個文件,.gitignoreREADME.md文件,這都是剛纔咱們勾選要求建立的。注意左邊的藍色的 Clone or download按鈕,點擊會出現下面界面,而後鼠標放在右邊那個小圖標上,會直接給予提示 Copy to clipboard。(這幾個英文要是還看不懂,那讓別學編程了)。

github_ok_can_clone.png-21.4kB

也就是說,咱們點擊那個 小圖標,會把前面的那個 ssh地址。git@github.com:yaowen369/TeachDemo.git複製到剪切板,(這不就是ctrl+c嘛)。

咱們的項目已經建立完畢了,換句話說,咱們已經在遠程服務器上建立了這個項目,那麼下面咱們的本地就已經能夠用了。

在你的電腦上,看你平時喜歡把代碼項目放在哪裏,就像我平時代碼都是放在D盤的某個文件夾,因此我是這樣操做的。

termial_git_clone.png-24.7kB

cd /d/code/github_blog/

git clone git@github.com:yaowen369/TeachDemo.git

我先經過cd命令進入了 d盤的code/github_blog/文件夾下,而後我再clone這個代碼。

先來解釋這兩條命令。

  • git clone : 將遠程服務器上的項目克隆到新建立的目錄中,解釋簡單點,將你在遠程服務器上的項目,第一次拉到本地,供你在本地使用。其實嚴格來說, 該過程是將 項目代碼,從服務器拉到 本地版本庫,而後再從 版本庫解析到 工做區。不過你關心那麼多幹嗎?記得 這個命令是 你在第一次想拉取某個本地沒有的項目時使用就好了。(爲何是第一次? 由於你第一次使用 git clone在本地弄好以後,從此再更新服務器上的代碼就使用 git pull了。)。
  • 那麼如今你理解github那個 標籤爲何叫作 Clone or download了吧。(若是你想查看github項目,直接下載也行。clone也行)

好的。如今咱們已經將 服務器上的代碼,拉到本地了。 可是這個目錄不是你eclipse下的項目目錄。你又不想重現建立項目,我想將eclipse下的某個項目直接和github的遠程服務器發生關聯,由於你平時寫代碼都是用eclipse啊。其實很簡單,將我D盤這個文件夾的全部文件,都複製到 你eclipse的某個項目的目錄下,就行了。。

圖片名稱:teach_demo_on_d.png
teach_demo_on_d.png-61.8kB

說簡單點,將該目錄下的 全部文件 都複製到 你eclipse的項目的代碼路徑下就ok了。。。
注意如下幾點:

某些人的電腦上可能沒有打開 顯示隱藏文件選項,因此要打開這個,由於你複製過程當中,真正起做用的就是 .git文件夾,最重要的隱藏文件都漏掉了,那你複製還有啥用?

由於咱們在 github上給項目取的名字就叫作 TeachDemo,爲了保險起見,咱們建議這個名字和eclipse工程中你的項目名稱保持一致。

另外 關於代碼路徑,建議不要帶中文字符,由於有些時候,帶中文路徑的代碼,編譯等可能有很奇怪的問題,因此你看個人電腦中代碼的文件路徑全都是英文的。

咱們已經拷貝完成了,而後你再 利用termial 進入到 你的 eclipse下的項目路徑,而後 git status,你看看會發生什麼。下面的操做就會了吧。

結束

到了這裏,咱們的基礎教程都已經講完了,只要求你記住六個名字,六個英文字符而已。會了以上的內容,對於你一我的開發項目來講,基本上 已經能應付95%的需求了。更進一步的內容,你能夠去廖雪峯的博客上學習。他寫的比較通俗易懂,而且涵蓋了平時團隊多人開發所使用的全部基本操做了。

有如下幾點想說:

  • 整篇文章,就是在講述 status,add,commit,push,pull,外加一個cd,記住這六個命令,六個單詞就夠了,
  • 更重要的是,這幾個命令,藉助 git status,tab鍵自動補全/提示功能,下一步該作什麼很簡單啊,有些東西掌握了方法剩下的學習成本很低的。
  • 包括什麼學習java,學習python,你會了其中任何一門,剩下的掌握其餘的,都很容易。 你學習java,那麼多的api方法你怎麼記得住? 因此要知道查詢API文檔的重要性,只要有個大概印象,而後知道怎麼搜索,能上google,百度這就夠了了,不然那麼多東西誰能記得住呢?
  • 固然, 無論是git,仍是java,或者任何一個領域學科。你要想深刻的去理解學習,那真的很難,要想精通,那對於咱們這種人來講基本是不可能的,git的命令多如牛毛,你要想成爲git的專家級人才,那學習過程,難的使人髮指,可是問題是,對於咱們平時使用來講,就那幾個命令就夠了啊,你要想成爲該領域的專家那就是 另一回事了。
  • 另外,英語水平不要太差,不過我想大學出來的,再加上各類翻譯軟件,google,百度,這也不是個什麼難的問題。

做者: www.yaoxiaowen.com

博客地址: www.cnblogs.com/yaoxiaowen/

github: https://github.com/yaowen369

歡迎對於本人的博客內容批評指點,若是問題,可評論或郵件(yaowen369@gmail.com)聯繫

歡迎轉載,轉載請註明出處.謝謝

相關文章
相關標籤/搜索