【轉】使用git和github管理自己的項目---基礎操作學習


本文轉載自:使用git和github管理自己的項目---基礎操作學習,進行了重新排版。二次轉載請注明原作出處。


我是通過看廖雪峰的git教程學習的,真的是極好的,以下是我學習過程中的總結,記錄下來,方便自己參考以熟悉git和github的使用。

除了廖雪峰的教程,還比較推薦在看完廖雪峰的教程之后,再看這樣一篇文章:使用git和github進行協同開發流程,和我的另一篇git的筆記:使用git和github管理自己的項目---真實開發環境的策略 ,深入了解github和git怎么在具體的項目開發中管理項目、有什么好的規范!

我這里記錄git的學習筆記,方便隨時參考,具體的git的原理github的原理集中式和分布式版本控制的區別版本控制的概念和原理Git和其他版本控制工具比如SVN的區別、以及更多的相關概念講解,請自己參見廖雪峰的git教程

我強烈推薦先看廖雪峰的git教程來系統化認識和學習git,然后自己整理一份具體的步驟方便平時開發時快速參考,或者直接參考我的。

先說一個比較好笑的事:廖雪峰的git教程中,剛開始的部分的瀏覽量有38萬,但是最后一頁教程的網頁的瀏覽量是1萬多。

以前因為覺得git、github比較難,所以一直拖著不學,現在去嘗試學習,一晚上就OK了

  • 重點之一是找到全面的、詳細的、生動的、高質量的教程。廖雪峰的git教程是我目前找到的最好的一個。之前找到的講解git用法的書《pro git》現在看來是沒有必要再看了!
  • 重點之二就是自己立即去學,其實沒什么難的,不要被貌似難的表象、概念唬住。
  • 重點之三是最好能自己做簡單的、系統的整理,方便自己隨時再回來查看、復習、參考,不至于出現這樣的情況:學完以后過一段時間之后再用,但是這時候發現忘了差不多了!
  • 重點之四就是立即動手去用,否則學完很快就忘了。

有錢的買mac,沒錢的用ubuntu--或者其他的linux發行版、被逼無奈的用Windows--但是被逼之余的自主時間一定要遠離Windows。

現在我的測試環境是ubuntu。

以對一個文件的管理為例,簡單說明git的使用。另外需要說明的是下面的實驗過程主要是只針對一個文件、并且修改的次數往往只有一次,而在真正的項目中,往往有大量的文件,也可能多次修改后才合并,合并時候的沖突可能也不只一兩個,等等。不過原理都是一樣的,我想說的是,不要局限在這個教程的示例上,請自己通過教程掌握基本的遠原理之后,自己推廣、去大量的實踐,最重要的是要制定一個好的版本控制的策略(合理分工、安排,還是盡可能的避免沖突為好),這個可以參考:使用git和github進行協同開發流程以及我的學習筆記使用git和github管理自己的項目---真實開發環境的策略

1.創建版本庫


  • sudo apt-get install git 先安裝git
  • 先創建目錄,作為倉庫
  • git init初始化倉庫,可以發現當前目錄下多了一個.git的目錄,這個目錄是Git來跟蹤管理版本庫的,沒事千萬不要手動修改這個目錄里面的文件,不然改亂了,就把Git倉庫給破壞了
  • vim readme.txt新建一個文本文件,比如往里面添加簡單的一行字符串
  • git add readme.txt 添加一個文件,比如readme.txt,如果目錄里面的所有文件都要添加,可以git add *
  • git commit-m "添加一個readme.txt文件" 將文件提交到倉庫,并加上說明(這時候是版本1)
    如果是第一次使用git,那么git commit可能報錯,所以需要你配置一些個人信息
  • git config --global user.email "you@example.com" 配置郵件
  • git config --global user.name "Your Name" 配置用戶名
  • 必須配置,否則后面的commit、push到遠程庫都會失敗
  • 然后再次git commit -m "添加一個readme.txt文件"
    才會成功

2.提交修改


  • 假如此時第一次修改了readme.txt文件
  • git status 讓我們時刻掌握倉庫當前的狀態。這時告訴我們,readme.txt被修改過了,但還沒有準備提交的修改。
  • git diff readme.txt 查看對readme.txt做了什么修改
  • git add readme.txt 提交修改和提交新文件是一樣,先git add
  • git status 可以再用git status查看倉庫的當前狀態,告訴我們,將要被提交的修改包括readme.txt
  • `git commit-m "第一次修改" 然后再git commit,并添加修改的描述(這時候是版本2)
  • git status 可以再執行git status看倉庫狀態,因為所有的都提交了,Git告訴我們當前沒有需要提交的修改,而且,工作目錄是干凈(working directory clean)的。

3.版本回退


  • 你可以像上面所說的那樣不停的提交新的文件、提交對文件的修改
  • 這時候第二次修改readme.txt文件
  • git add readme.txt 先git add
  • git commit -m "第二次修改" 提交第二次修改(這時候是版本3)
  • git log 顯示從最近到最遠的提交日志,具體顯示的內容自己試一試看看
  • git log --pretty=oneline 如果嫌輸出信息太多,看得眼花繚亂,試試加上--pretty=oneline參數
  • 這篇教程去理解為什么Git的版本號要這么長,Git的版本號類似:3628164fb26d48395383f8f31179f24e0882e1e0 這樣的特別長的十六進制數。
  • git reset --hard HEAD^ 會回退到上一個版本,也就是從版本3回退到版本2
  • 在Git中,用HEAD表示當前版本,也就是最新的提交3628164...882e1e0(注意我的提交ID和你的肯定不一樣),上一個版本就是HEAD,上上一個版本就是HEAD,當然往上100個版本寫100個比較容易數不過來,所以寫成HEAD~100
  • vim readme.txt 可以看到此時的readme.txt文件就是版本2時候的內容,回退成功!
  • git log 此時看到版本3的信息沒有了
  • git reset --hard 3628164 通過命令行上的歷史信息(假如你沒清屏的話),找到版本3 的版本號,不一定要全部的版本號,就像這個命令的例子,只要前面的約7、8位這樣就可以指定回到版本3
  • vim readme.txt 看到的是第三版本的readme.txt文件的內容,所以又回來了
  • Git的版本回退速度非常快,因為Git在內部有個指向當前版本的HEAD指針,當你回退版本的時候,Git僅僅是把HEAD從指向你要回退的那個版本
  • `git reflog 記錄你的每一次命令,最先顯示的是這個命令執行之后的版本的版本號的前七位,這樣就算你清屏了或者重啟了,也能找到某個版本的版本號,就可以輕松回退到那個版本

4.工作區、版本庫和暫存區


工作區:就是你在電腦里能看到的目錄,比如我的learngit文件夾就是一個工作區。

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

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

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

  1. 第一步是用git add把文件添加進去,實際上就是把文件修改添加到暫存區;
  2. 第二步是用git commit提交更改,實際上就是把暫存區的所有內容提交到當前分支。

因為我們創建Git版本庫時,Git自動為我們創建了唯一一個master分支,所以,現在,git commit就是往master分支上提交更改。

你可以簡單理解為,需要提交的文件修改通通放到暫存區,然后,一次性提交暫存區的所有修改。

詳細知識見這篇教程。必須理解暫存區、工作區、版本庫。這些都是是Git非常重要的概念,弄明白了這些概念,就弄明白了Git的很多操作到底干了什么。沒弄明白的話,請反復看!!

5.管理修改


為什么Git比其他版本控制系統設計得優秀,因為Git跟蹤并管理的是修改,而非文件。

什么是修改?比如你新增了一行,這就是一個修改,刪除了一行,也是一個修改,更改了某些字符,也是一個修改,刪了一些又加了一些,也是一個修改,甚至創建一個新文件,也算一個修改。

通過實例講解什么叫跟蹤修改,要想理解,請參考原文結合暫存區的知識理解:

  • vim readme.txt 編輯文件,比如添加新的一行
  • git add readme.txt 添加,但是不提交
  • vim readme.txt 再編輯文件,比如再添加一行
  • git commit -m "修改兩次,添一次,提交一次" 提交
  • git status 看到的效果是:只提交了第一次的修改,第二次的修改沒有提交

那怎么提交第二次修改呢?你可以繼續git addgit commit,也可以別著急提交第一次修改,先git add第二次修改,再git commit,也就是第一次修改 -> git add -> 第二次修改 -> git add -> git commit,就相當于把兩次修改合并后一塊提交了。

6.撤銷修改


第一種情況

  • 修改了readme.txt文件,還沒有git add 和git commit
  • 但是在你提交之前發現這次修改有問題。既然錯誤發現得很及時,就可以很容易地糾正它。你可以手動把文件恢復到上一個版本的狀態。
  • git checkout -- readme.txt 也可以通過命令撤銷修改,這條命令的意思就是,把readme.txt文件在工作區的修改全部撤銷
  • 無論是文件修改后值存在于工作區還沒有放到暫存區,還是已經添加到暫存區,總之這個命令就是讓這個文件回到最近一次git commit或git add時的狀態。
  • 查看文件,內容果然復原了。git checkout -- file命令中的--
    很重要,沒有--
    ,就變成了“切換到另一個分支”的命令,我們在后面的分支管理中會再次遇到git checkout命令。

第二種情況

  • 修改了readme.txt文件,而且執行了git add readme.txt
  • 慶幸的是你在 git commit 之前發現了這個問題
  • git status 查看一下,修改只是添加到了暫存區,還沒有提交
  • git reset HEAD readme.txt 可以把暫存區的修改撤銷掉,重新放回工作區。git reset命令既可以回退版本,也可以把暫存區的修改回退到工作區。當我們用HEAD時,表示最新的版本。
  • git status 查看一下,現在暫存區是干凈的,工作區有修改
  • git checkout -- readme.txt 還記得第一種情況中如何丟棄工作區的修改吧

第三種情況

現在,假設你不但改錯了東西,還從暫存區提交到了版本庫,怎么辦呢?還記得版本回退一節嗎?可以回退到上一個版本。不過,這是有條件的,就是你還沒有把自己的本地版本庫推送到遠程。

還記得Git是分布式版本控制系統嗎?我們后面會講到遠程版本庫,一旦你把錯誤的修改(如果是影響很大的錯誤)提交推送到遠程版本庫,你就真的慘了……

區別對待本地版本庫和遠程版本庫!

7.刪除文件


在Git中,刪除也是一個修改操作

  • 添加一個新的文件 test.txt
  • git add test.txt
  • git commit test.txt -m "再次新增一個文件"
  • 一般情況下,你通常會在文件管理器中把沒用的文件刪除,或者直接rm test.txt
  • `git status 這個時候,Git知道你刪除了文件,因此,工作區和版本庫就不一致了,git status命令會立刻告訴你哪些文件被刪除了
  • 現在你有兩個選擇,一是確實從版本庫中刪除該文件,那就git rm test.txt,然后git commit 文件就從版本庫中刪除了
  • 另一種情況是刪除錯了,因為版本庫里還有,所以可以輕松地將誤刪除的文件恢復到最新版本git checkout -- test.txt,git checkout其實使用版本庫中的版本替換工作區的版本,無論工作區是修改還是刪除,都可以“一鍵還原”

8.添加遠程庫


要想學習這部分的知識,請先參考下面的:a.配置連接遠程倉庫Github

  • 假如現在你已經配置好github,并且在github上添加了learngit倉庫。
  • git remote add origin git@github.com:michaelliao/learngit.git 這個命令是在本地的learngit倉庫下執行的,前面通過learngit倉庫為例我們已經講過在本地創建和操作git倉庫。這兩個地方的倉庫名不需要相同,因為會通過在本地的倉庫目錄下執行這條命令(命令中包含遠程庫的名字)已經將兩者建立了聯系
  • 請千萬注意,把上面的michaelliao替換成你自己的GitHub賬戶名,否則,你在本地關聯的就是我的遠程庫,關聯沒有問題,但是你以后推送是推不上去的,因為你的SSH Key公鑰不在我的賬戶列表中。
  • git push -u origin master 把本地庫的所有內容推送到遠程庫上。把本地庫的內容推送到遠程,用git push命令,實際上是把當前分支master推送到遠程。由于遠程庫是空的,我們第一次推送master分支時,加上了-u參數,Git不但會把本地的master分支內容推送的遠程新的master分支,還會把本地的master分支和遠程的master分支關聯起來,在以后的推送或者拉取時就可以簡化命令。
  • 然后去Github對應的遠程庫看看,都已經推送上去了。
  • 此后,每次本地提交后,只要有必要,就可以使用命令git push origin master推送最新修改。

這樣你就可以在Github上托管你的項目代碼、vim的配置文件和插件、重要的文檔……

現在我的vim的配置文件和插件已經同步到Github上了:https://github.com/xumenger/m...

另外推薦我的關于vim配置的文章::http://segmentfault.com/a/119...

9.從遠程庫克隆


  • 假設我的github上面有一個遠程庫,但是本地沒有,需要克隆到本地,遠程庫的名字叫'gitskills'
  • git clone git@github.com:michaelliao/gitskills.git 克隆一個本地庫
  • cd gitskills 進入克隆下來的本地庫,默認的名字是和github上的一樣的
  • ls -al 可以看到本地的克隆庫里面是和遠程庫里面的一樣的
  • 如果有多個人協作開發,那么每個人各自從遠程克隆一份就可以了。

你也許還注意到,GitHub給出的地址不止一個,還可以用https://github.com/michaellia...這樣的地址。實際上,Git支持多種協議,默認的git://使用ssh,但也可以使用https等其他協議。

使用https除了速度慢以外,還有個最大的麻煩是每次推送都必須輸入口令,但是在某些只開放http端口的公司內部就無法使用ssh協議而只能用https。

10.分支管理


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

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

其他版本控制系統如SVN等都有分支管理,但是用過之后你會發現,這些版本控制系統創建和切換分支比蝸牛還慢,簡直讓人無法忍受,結果分支功能成了擺設,大家都不去用。

但Git的分支是與眾不同的,無論創建、切換和刪除分支,Git在1秒鐘之內就能完成!無論你的版本庫是1個文件還是1萬個文件。

11.創建和合并分支


首先教程中會詳細講解分支的原理(分支、指針、工作區……),一定要好好看!!看完之后你才能對你的創建分支和合并分支的操作不只是會用,更能在用的時候沒有任何疑惑!反正能學到更多的知識,何樂而不為!

另外推薦這樣的博客:使用git和github進行協同開發流程以及我的學習筆記使用git和github管理自己的項目---真實開發環境的策略

版本回退里,你已經知道,每次提交,Git都把它們串成一條時間線,這條時間線就是一個分支。截止到目前,我們練習的learngit,只有一條時間線,在Git里,這個分支叫主分支,即master分支。HEAD嚴格來說不是指向提交,而是指向master,master才是指向提交的,所以,HEAD指向的就是當前分支。

開始實戰:

  • git checkout -b dev 創建一個新的分支:dev,并且會切換到dev分支。所以這條命令有兩個作用。git checkout命令加上-b參數表示創建并切換,相當于以下兩條命令:git branch devgit checkout dev
  • 補充:所有的git管理的項目剛開始時候默認有一條分支:master
  • git branch 查看當前所在的分支。git branch命令會列出所有分支,當前分支前面會標一個*號。
  • 因為切換到dev分支,所以我們現在可以在dev分支上正常提交,比如對readme.txt做一個修改
  • git add readme.txt
  • git commit -m "提交到dev分支"
  • git checkout master
    現在,dev分支的工作完成,我們就可以切換回master分支
  • 注意:切換回master分支后,再查看一個readme.txt文件,剛才添加的內容不見了!因為那個提交是在dev分支上,而master分支此刻的提交點并沒有變
  • git merge dev 這是在master分支上執行的命令,作用是:把dev分支上的工作成果合并到master分支上
  • git merge命令用于合并指定分支到當前分支。合并后,再查看readme.txt的內容,就可以看到,和dev分支的最新提交是完全一樣的。注意到上面的Fast-forward信息,Git告訴我們,這次合并是“快進模式”,也就是直接把master指向dev的當前提交,所以合并速度非常快。當然,也不是每次合并都能Fast-forward,我們后面會將其他方式的合并。
  • git branch -d dev 合并完成之后,可以放心的刪除dev分支了
  • git branch 刪除后,查看branch,只剩下master了

12.解決沖突


教程中有詳細的圖文說明,很形象,很好!一定要參考!

人生不如意之事十之八九,合并分支往往也不是一帆風順的。

  • git checkout -b feature1 創建新的分支feature1,并且換到這個分支,進行新的實驗
  • 在feature1分支下,假如將readme.txt的最后一行由"test branch" 改為"test feature1"
  • git add readme.txt
  • git commit -m "在feature1上修改readme.txt的最后一行" 在feature1分支上提交
  • git checkout master 切換到master分支。Git還會自動提示我們當前master分支比遠程的master分支要超前1個提交。
  • 在master分支下,假如將readme.txt的最后一行由"test branch" 改為"test master"因為上面的是在feature1上進行的修改,所以切換回master之后,看到的文件并不是在feature1上修改后的文件
  • git add readme.txt
  • git commit -m "又在master上修改了readme.txt文件" 在master上也提交修改
  • 現在,master分支和feature1分支各自都分別有新的提交
  • git merge feature1 在master分支上執行該命令,與feature1分支合并。這種情況下,Git無法執行“快速合并”,只能試圖把各自的修改合并起來,但這種合并就可能會有沖突,果然沖突了!Git告訴我們,readme.txt文件存在沖突,必須手動解決沖突后再提交
  • git status git status也可以告訴我們沖突的文件
  • 這時候使用vim等編輯器打開readme.txt文件可以看到已經在readme.txt文件中將沖突的信息已經添加到里面了,Git用<<<<<<<=======>>>>>>>標記出不同分支的內容
  • 然后我們編輯readme.txt文件,處理沖突,將內容改成我們想要的樣子
  • git add readme.txt
  • git commit -m "解決沖突" 在master上提交
  • git log --graph --pretty=oneline --abbrev-commit 用帶參數的git log可以看到分支的合并情況。用git log --graph命令可以看到分支合并圖。
  • git branch -d feature1 最后刪除feature分支,完成工作。

2015.09.09 今天就學到這里,實在太晚了,趕緊睡覺,明天還得工作!什么都沒有身體重要!明天繼續: 分支管理策略

a.配置連接遠程倉庫Github


首先看這篇文章了解git和SVN的區別,畢竟現在必須在工作中使用的就是SVN,所以還是弄清楚兩者的區別。

Git是分布式版本控制系統,同一個Git倉庫,可以分布到不同的機器上。怎么分布呢?最早,肯定只有一臺機器有一個原始版本庫,此后,別的機器可以“克隆”這個原始版本庫,而且每臺機器的版本庫其實都是一樣的,并沒有主次之分。

實際情況往往是這樣,找一臺電腦充當服務器的角色,每天24小時開機,其他每個人都從這個“服務器”倉庫克隆一份到自己的電腦上,并且各自把各自的提交推送到服務器倉庫里,也從服務器倉庫中拉取別人的提交。

完全可以自己搭建一臺運行Git的服務器,不過現階段,為了學Git先搭個服務器絕對是小題大作。好在這個世界上有個叫GitHub的神奇的網站,從名字就可以看出,這個網站就是提供Git倉庫托管服務的,所以,只要注冊一個GitHub賬號,就可以免費獲得Git遠程倉庫。

在繼續閱讀后續內容前,請自行注冊GitHub賬號。由于你的本地Git倉庫和GitHub倉庫之間的傳輸是通過SSH加密的,所以,需要一點設置:

  1. 創建SSH Key。在用戶目錄下,看看有沒有.ssh目錄,如果有,再看看這個目錄下有沒有id_rsaid_rsa.pub這兩個文件,如果已經有了,可直接跳到下一步。如果沒有,打開Shell(Windows下打開Git Bash),創建SSH Key,輸入命令ssh-keygen -t rsa -C "youremail@example.com",你需要把郵件地址換成你自己的郵件地址,然后一路回車,使用默認值即可,由于這個Key也不是用于軍事目的,所以也無需設置密碼。如果一切順利的話,可以在用戶主目錄里找到.ssh目錄,里面有id_rsaid_rsa.pub兩個文件,這兩個就是SSH Key的秘鑰對,id_rsa是私鑰,不能泄露出去,id_rsa.pub是公鑰,可以放心地告訴任何人。
  2. 登陸GitHub,打開“Account settings”,“SSH Keys”頁面.然后,點“Add SSH Key”,填上任意Title,在Key文本框里粘貼id_rsa.pub文件的內容:
  1. 點“Add Key”,你就應該看到已經添加的Key:

注意現在的Github的頁面的布局可能和圖片中顯示有細小的差別,不過相信你能找到對應的操作!

為什么GitHub需要SSH Key呢?因為GitHub需要識別出你推送的提交確實是你推送的,而不是別人冒充的,而Git支持SSH協議,所以,GitHub只要知道了你的公鑰,就可以確認只有你自己才能推送。

當然,GitHub允許你添加多個Key。假定你有若干電腦,你一會兒在公司提交,一會兒在家里提交,只要把每臺電腦的Key都添加到GitHub,就可以在每臺電腦上往GitHub推送了。

最后友情提示,在GitHub上免費托管的Git倉庫,任何人都可以看到喔(但只有你自己才能改)。所以,不要把敏感信息放進去。

如果你不想讓別人看到Git庫,有兩個辦法,一個是交點保護費,讓GitHub把公開的倉庫變成私有的,這樣別人就看不見了(不可讀更不可寫)。另一個辦法是自己動手,搭一個Git服務器,因為是你自己的Git服務器,所以別人也是看不見的。這個方法我們后面會講到的,相當簡單,公司內部開發必備。

現在的情景是,你已經在本地創建了一個Git倉庫后,又想在GitHub創建一個Git倉庫,并且讓這兩個倉庫進行遠程同步,這樣,GitHub上的倉庫既可以作為備份,又可以讓其他人通過該倉庫來協作,真是一舉多得。具體可以見教程

首先,登陸GitHub,然后,在右上角找到“Create a new repo”按鈕,創建一個新的倉庫:


在Repository name填入learngit,其他保持默認設置,點擊“Create repository”按鈕,就成功地創建了一個新的Git倉庫:

目前,在GitHub上的這個learngit倉庫還是空的,GitHub告訴我們,可以從這個倉庫克隆出新的倉庫,也可以把一個已有的本地倉庫與之關聯,然后,把本地倉庫的內容推送到GitHub倉庫。


本文轉載自:使用git和github管理自己的項目---基礎操作學習,進行了重新排版。二次轉載請注明原作出處。

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

推薦閱讀更多精彩內容

  • 1.git的安裝 1.1 在Windows上安裝Git msysgit是Windows版的Git,從https:/...
    落魂灬閱讀 12,713評論 4 54
  • 1. 安裝 Github 查看是否安裝git: $ git config --global user.name "...
    Albert_Sun閱讀 13,719評論 9 163
  • 1.馮侖在《野蠻生長》里有過類似的觀點,靈活的小團隊+中臺是未來團隊的發展方向。發現敵人首腦(靈活的小團隊),呼叫...
    gqyjlu閱讀 441評論 0 0
  • 晚飯后在客廳看了,動物世界我看到了犀牛,和大象和猴子,獵豹和采在陸地上奔跑,看到老鷹看到狗老虎獅子
    高金鑫a閱讀 159評論 0 0
  • 這句話可能在電視中,文章中都看到過很多次,再堅持一下,也許就成功了。 腦海中,那幅畫特別清晰。兩個人在打地洞挖寶藏...
    張磊沙閱讀 311評論 2 0