前言
Git是一個分布式的版本控制工具,本篇文章從介紹Git開始,重點在於介紹Git的基本命令和使用技巧,讓你嘗試使用Git的同時,體驗到原來一個版 本控制工具可以對開發產生如此之多的影響,文章分為兩部分,第一部分介紹Git的一些常用命令,其中穿插介紹Git的基本概念和原理,第二篇重點介紹 Git的使用技巧,最后會在Git Hub上創建一個開源項目開啟你的Git實戰之旅
Git是什么
Git在Wikipedia上的定義:它是一個免費的、分布式的版本控制工具,或是一個強調了速度快的源代碼管理工具。Git最初被Linus Torvalds開發出來用於管理Linux內核的開發。每一個Git的工作目錄都是一個完全獨立的代碼庫,並擁有完整的歷史記錄和版本追蹤能力,不依賴 於網絡和中心服務器。
Git的出現減輕了許多開發者和開源項目對於管理分支代碼的壓力,由於對分支的良好控制,更鼓勵開發者對自己感興趣的項目做出貢獻。其實許多開源項目 包括Linux kernel, Samba, X.org Server, Ruby on Rails,都已經過渡到使用Git作為自己的版本控制工具。對於我們這些喜歡寫代碼的開發者嘛,有兩點最大的好處,我們可以在任何地點(在上班的地鐵 上)提交自己的代碼和查看代碼版本;我們可以開許許多多個分支來實踐我們的想法,而合並這些分支的開銷幾乎可以忽略不計。
Git 初始化
現在進入本篇文章真正的主題,介紹一下Git的基本命令和操作,會從Git的版本庫的初始化,基本操作和獨有的常用命令三部分着手,讓大家能夠開始使用Git。
Git通常有兩種方式來進行初始化:
git clone: 這是較為簡單的一種初始化方式,當你已經有一個遠程的Git版本庫,只需要在本地克隆一份,例如'git clone git://github.com/someone/some_project.git some_project'命令就是將'git://github.com/someone/some_project.git'這個URL地址的遠程版 本庫完全克隆到本地some_project目錄下面
git init和git remote:這種方式稍微復雜一些,當你本地創建了一個工作目錄,你可以進入這個目錄,使用 git init 命令進行初始化,Git以后就會對該目錄下的文件進行版本控制,這時候如果你需要將它放到遠程服務器上,可以在遠程服務器上創建一個目錄,並把 可訪問的URL記錄下來,此時你就可以利用 git remote add 命令來增加一個遠程服務器端,例如'git remote add origin git://github.com/someone/another_project.git'這條命令就會增加URL地址為'git: //github.com/someone/another_project.git',名稱為origin的遠程服務器,以后提交代碼的時候只需要使用 origin別名即可
Git 基本命令
現在我們有了本地和遠程的版本庫,讓我們來試着用用Git的基本命令吧:
git pull:從版本庫(既可以是遠程的也可以是本地的)將代碼更新到本地,例如:'git pull origin master'就是將origin這個版本庫的代碼更新到本地的master主枝,該功能類似於SVN的update
git add:將所有改動的文件(新增和有變動的)放在暫存區,由git進行管理
git rm:從當前的工作空間中和索引中刪除文件,例如'git rm app/model/user.rb',移除暫存區
git commit:提交當前工作空間的修改內容,類似於SVN的commit命令,例如'git commit -m "story #3, add user model"',提交的時候必須用-m來輸入一條提交信息
git push:將本地commit的代碼更新到遠程版本庫中,例如'git push origin branchname'就會將本地的代碼更新到名為orgin的遠程版本庫中
git log:查看歷史日志
git revert:還原一個版本的修改,必須提供一個具體的Git版本號,例如'git revert bbaf6fb5060b4875b18ff9ff637ce118256d6f20',Git的版本號都是生成的一個哈希值、
上面的命令幾乎都是每個版本控制工具所公有的,下面就開始嘗試一下Git獨有的一些命令:
Git 獨有命令
git branch:對分支的增、刪、查等操作,例如 git branch new_branch 會從當前的工作版本創建一個叫做new_branch的新分支,git branch -D new_branch 就會強制刪除叫做new_branch的分支,git branch 就會列出本地所有的分支
git checkout:Git的checkout有兩個作用,其一是在 不同的branch之間進行切換,例如 'git checkout new_branch'就會切換到new_branch的分支上去;另一個功能是 還原代碼的作用,例如git checkout app/model/user.rb 就會將user.rb文件從上一個已提交的版本中更新回來,未提交的內容全部會回滾
git rebase:用下面兩幅圖解釋會比較清楚一些,rebase命令執行后,實際上是將分支點從C移到了G,這樣分支也就具有了從C到G的功能 (使歷史更加簡潔明了)

git reset:回滾到指定的版本號,我們有A-G提交的版本,其中C 的版本號是 bbaf6fb,我們執行了'git reset bbaf6fb'那么結果就只剩下了A-C三個提交的版本

git stash:將當前未提交的工作存入Git工作棧中,時機成熟的時候再應用回來,這里暫時提一下這個命令的用法,后面在技巧篇會重點講解
git config:新增、更改Git的各種設置,例如:git config branch.master.remote origin 就將master的遠程版本庫設置為別名叫做origin版本庫
git tag:將某個版本打上一個標簽,例如:git tag revert_version bbaf6fb50 來標記這個被你還原的版本,那么以后你想查看該版本時,就可以使用 revert_version標簽名,而不是哈希值了
Git 其他命令
add #添加文件內容至索引
branch #列出、創建或刪除分支
checkout #檢出一個分支或路徑到工作區
clone #克隆一個版本庫到一個新目錄
commit #最近一次的提交,--amend修改最近一次提交說明
diff #顯示提交之間、提交和工作區之間等的差異
fetch #從另外一個版本庫下載對象和引用
init #創建一個空的 Git 版本庫或重新初始化一個已存在的版本庫
log #顯示提交日志 --stat 具體文件的改動
reflog #記錄丟失的歷史
merge #合並兩個或更多開發歷史,--squash 把分支所有提交合並成一個提交
mv #移動或重命名一個文件、目錄或符號鏈接
pull #獲取並合並另外的版本庫或一個本地分支(相當於git fetch和git merge)
push #更新遠程引用和相關的對象
rebase #本地提交轉移至更新后的上游分支中
reset #重置當前HEAD到指定狀態
rm #從工作區和索引中刪除文件
show #顯示各種類型的對象
status #顯示工作區狀態
tag #創建、列出、刪除或校驗一個GPG簽名的 tag 對象
cherry-pick #從其他分支復制指定的提交,然后導入到現在的分支
git merge --squash issue1
git分支命令
創建分支:
git branch linux #創建分支
git checkout linux #切換分支
git branch #查看當前分支情況,當前分支前有*號
git add readme.txt #提交到暫存區
git commit -m “new branch” #提交到git版本倉庫
git checkout master #我們在提交文件后再切回master分支
分支合並:(合並前必須保證在master主干上)
git branch #查看在哪個位置
git merge Linux #合並創建的Linux分支(–no–ff默認情況下,Git執行”快進式合並”(fast-farward merge),會直接將Master分支指向Develop分支。使用–no–ff參數后,會執行正常合並,在Master分支上生成一個新節點。)
git branch -d linux #確認合並后刪除分支
如果有沖突:
git merge linux #合並Linux分支(沖突)
Auto-merging readme.txt
CONFLICT (content): Merge conflict in readme.txt
Automatic merge failed; fix conflicts and then commit the result.
#那么此時,我們在master與linux分支上都分別對中readme文件進行了修改並提交了,那這種情況下Git就沒法再為我們自動的快速合並了,它只能告訴我們readme文件的內容有沖突,需要手工處理沖突的內容后才能繼續合並
自己修改完readme.txt文件后再次提交


–no–ff原理圖
git全局配置
yum install git #安裝Git git config –global user.name “xubusi” #配置git使用用戶 git config –global user.email “xubusi@mail.com” #配置git使用郵箱 git config –global color.ui true #加顏色 git config –list #所有配置的信息(上面的結果) user.name=xubusi user.email=xubusi@mail.com color.ui=true
.git目錄結構
Git之所以能夠提供方便的本地分支等特性,是與它的文件存儲機制有關的。Git存儲版本控制信息時使用它自己定義的一套文件系統存儲機制,在代碼根目錄下有一個.git文件夾,會有如下這樣的目錄結構:
HEAD branches/ config description hooks/ index info/ objects/ refs/
有幾個比較重要的文件和目錄需要解釋一下:
HEAD:文件存放根節點的信息,其實目錄結構就表示一個樹型結構,Git采用這種樹形結構來存儲版本信息, 那么HEAD就表示根;
refs:目錄存儲了你在當前版本控制目錄下的各種不同引用(引用指的是你本地和遠程所用到的各個樹分支的信息),它有heads、 remotes、stash、tags四個子目錄,分別存儲對不同的根、遠程版本庫、Git棧和標簽的四種引用,你可以通過命令'git show-ref'更清晰地查看引用信息;
logs:目錄根據不同的引用存儲了日志信息。因此,Git只需要代碼根目錄下的這一個.git目錄就可以記錄完 整的版本控制信息,而不是像SVN那樣根目錄和子目錄下都有.svn目錄。那么下面就來看一下Git與SVN的區別吧
.gitigmore: 放一些不需要git管理的文件(例:IDE的工作目錄 .idea,)
Git與SVN的不同
SVN(Subversion)是當前使用最多的版本控制工具。與它相比較,Git最大的優勢在於兩點:易於本地增加分支和分布式的特性。
下面兩幅圖可以形象的展示Git與SVN的不同之處

GIT對於易於本地增加分支,圖中Git本地和服務器端結構都很靈活,所有版本都存儲在一個目錄中,你只需要進行分支的切換即可達到在某個分支工作的效果。
SVN則完全不同,如果你需要在本地試驗一些自己的代碼,只能本地維護多個不同的拷貝,每個拷貝對應一個SVN服務器地址。
分布式對於Git而言,你可以本地提交代碼,所以在上面的圖中,Git有利於將一個大任務分解,進行本地的多次提交,而SVN只能在本地進行大量的一 次性更改,導致將來合並到主干上造成巨大的風險。Git的代碼日志是在本地的,可以隨時查看。SVN的日志在服務器上的,每次查看日志需要先從服務器上下 載下來。我工作的小組,代碼服務器在美國,每次查看小組幾年前所做的工作時,日志下載就需要十分鍾,這不能不說是一個痛苦。后來我們遷移到Git上,利用 Git日志在本地的特性,我用Ruby編寫了一個Rake腳本,可以查看某個具體任務的所有代碼歷史,每次只需要幾秒鍾,大大方便我的工作。當然分布式並 不是說用了Git就不需要一個代碼中心服務器,如果你工作在一個團隊里,還是需要一個服務器來保存所有的代碼的。
實際的例子:
以前我所 在的小組使用SVN作為版本控制工具,當我正在試圖增強一個模塊,工作做到一半,由於會改變原模塊的行為導致代碼服務器上許多測試的失敗,所以並沒有提交 代碼。這時候上級對我說,現在有一個很緊急的Bug需要處理, 必須在兩個小時內完成。我只好將本地的所有修改diff,並輸出成為一個patch文件,然后回滾有關當前任務的所有代碼,再開始修改Bug的任務,等到 修改好后,在將patch應用回來。前前后后要完成多個繁瑣的步驟,這還不計中間代碼發生沖突所要進行的工作量。
可是如果使用Git, 我們只需要開一個分支或者轉回到主分支上,就可以隨時開始Bug修改的任務,完成之后,只要切換到原來的分支就可以優雅的繼續以前的任務。只要你願意,每 一個新的任務都可以開一個分支,完成后,再將它合並到主分支上,輕松而優雅。
gitlab介紹
安裝服務相關命令
安裝有可能的依賴:
yum install openssh-server
yum install postfix
yum install cronie
安裝gitlab:
curl -sS https://packages.gitlab.com/install/repositories/gitlab/gitlab-ce/script.rpm.sh #下載數據源
yum install gitlab-ce
安裝完成后:
gitlab-ctl reconfigure #使配置文件生效 但是會初始化除了gitlab.rb之外的所有文件
gitlab-ctl status #查看狀態
gitlab-ctl stop #停服務
gitlab-ctl start #起服務
gitlab-ctl tail #查看日志的命令(Gitlab 默認的日志文件存放在/var/log/gitlab 目錄下)
如下表示啟動成功:(全是run,有down表示有的服務沒啟動成功

然后打開瀏覽器輸入ip或者域名
相關目錄文件信息
相關目錄
.git/config #版本庫特定的配置設置,可用--file修改
~/.gitconfig #用戶特定的配置設置,可用--global修改
/var/opt/gitlab/git-data/repositories/root #庫默認存儲目錄
/opt/gitlab #是gitlab的應用代碼和相應的依賴程序
/var/opt/gitlab #此目錄下是運行gitlab-ctl reconfigure命令編譯后的應用數據和配置文件,不需要人為修改配置
/etc/gitlab #此目錄下存放了以omnibus-gitlab包安裝方式時的配置文件,這里的配置文件才需要管理員手動編譯配置
/var/log/gitlab #此目錄下存放了gitlab各個組件產生的日志
/var/opt/gitlab/backups/ #備份文件生成的目錄
相關文件
/opt/gitlab/embedded/service/gitlab-rails/config #配置文件(修改clone的ip地址)
/etc/gitlab/gitlab.rb #設置相關選項進行配置(gitlab地址就在這)
/var/opt/gitlab/git-data #Git存儲庫數據(默認
總結
本篇介紹了Git的基本概念、一些常用命令和原理,大家可以嘗試動手體會一下,下一篇會重點介紹Git命令的使用技巧,Git附帶的工具,最后會在Git Hub上創建一個開源項目。
一段關於revert痛苦的經歷:https://blog.csdn.net/u013066244/article/details/79920012
