Git 與 SVN 區別
Git是一個開源的分布式版本控制系統,用于敏捷高效地處理任何或小或大的專案,Git 是 Linus Torvalds 為了幫助管理 Linux 內核開發而開發的一個開放原始碼的版本控制軟體,Git 與常用的版本控制工具 CVS, Subversion 等不同,它采用了分布式版本庫的方式,不必服務器端軟體支持,
GIT不僅僅是個版本控制系統,它也是個內容管理系統(CMS),作業管理系統等,如果你是一個具有使用SVN背景的人,你需要做一定的思想轉換,來適應GIT提供的一些概念和特征,Git 與 SVN 區別點:
1、GIT是分布式的,SVN不是:這是GIT和其它非分布式的版本控制系統,例如SVN,CVS等,最核心的區別,
2、GIT把內容按元資料方式存盤,而SVN是按檔案:所有的資源控制系統都是把檔案的元資訊隱藏在一個類似.svn,.cvs等的檔案夾里,
3、GIT分支和SVN的分支不同:分支在SVN中一點不特別,就是版本庫中的另外的一個目錄,
4、GIT沒有一個全域的版本號,而SVN有:目前為止這是跟SVN相比GIT缺少的最大的一個特征,
5、GIT的內容完整性要優于SVN:GIT的內容存盤使用的是SHA-1哈希演算法,這能確保代碼內容的完整性,確保在遇到磁盤故障和網路問題時降低對版本庫的破壞,
Git作業原理
Git作業流程可以分一下步驟:
- 克隆 Git 資源作為作業目錄;
- 在克隆的資源上添加或修改檔案;
- 如果其他人修改了,你可以更新資源;
- 在提交前查看修改,提交修改;
- 在修改完成后,如果發現錯誤,可以撤回提交并再次修改并提交;

Git 作業區、暫存區和版本庫:
- 作業區:就是你在電腦里能看到的目錄,
- 暫存區:英文叫stage, 或index,一般存放在"git目錄"下的index檔案(.git/index)中,所以我們把暫存區有時也叫作索引(index),
- 版本庫:作業區有一個隱藏目錄.git,這個不算作業區,而是Git的版本庫,

常見操作
全域配置用戶資訊
git config --global user.name "smyhvae"
git config --global user.email "[email protected]"
Git 創建倉庫
git init repository
如果當前目錄下有幾個檔案想要納入版本控制,需要先用 git add 命令告訴 Git 開始對這些檔案進行跟蹤,然后提交:
$ git add *.c
$ git add README
$ git commit -m 'initial project version'
從現有倉庫克隆
$ git clone git://github.com/test/test.git
Git基本操作命令
git init
創建專案命令,在目錄中創建新的 Git 倉庫, 你可以在任何時候、任何目錄中這么做,完全是本地化的,在目錄中執行 git init,就可以創建一個 Git 倉庫,
$ mkdir test
$ cd test
$ git init
git clone
使用 git clone 拷貝一個 Git 倉庫到本地,讓自己能夠查看該專案,或者進行修改,
$ git clone git://github.com/test/test.git
git push
其作用是將本地分支的更新推送到遠程主機
$ git push <遠程主機名> <本地分支名>:<遠程分支名>
git pull
其作用是將遠程主機更新到本地分支
$ git pull <遠程主機名> <本地分支名>:<遠程分支名>
git add
git add 命令可將該檔案添加到快取,如我們添加以下兩個檔案:
$ touch README
$ touch hello.php
$ ls
README hello.php
$ git status -s
?? README
?? hello.php
$
git status
命令用于查看專案的當前狀態
$ git add README hello.php
$ git status -s
A README
A hello.php
$
git diff
git diff 命令顯示已寫入快取與已修改但尚未寫入快取的改動的區別,git diff 有兩個主要的應用場景:
尚未快取的改動:git diff
查看已快取的改動: git diff --cached
查看已快取的與未快取的所有改動:git diff HEAD
顯示摘要而非整個 diff:git diff --stat
$ git status -s
A README
AM hello.php
$ git diff
diff --git a/hello.php b/hello.php
git commit
使用 git add 命令將想要快照的內容寫入了快取, 而執行 git commit 記錄快取區的快照,Git 為你的每一個提交都記錄你的名字與電子郵箱地址,所以第一步需要配置用戶名和郵箱地址,
$ git config --global user.name 'admin'
$ git config --global user.email [email protected]
$ git add hello.php
$ git status -s
A README
A hello.php
$ git commit -m 'test comment from test.cn'
[master (root-commit) 85fc7e7] test comment from test.cn
2 files changed, 4 insertions(+)
create mode 100644 README
create mode 100644 hello.php
現在我們已經記錄了快照,如果我們再執行 git status:
$ git status
# On branch master
nothing to commit (working directory clean)
git log
查看歷史提交記錄
$ git log
commit 88afe0e02adcdfea6844bb627de97da21eb10af1
Merge: 14b4dca d7e7346
Author: admin
Date: Sun Mar 1 15:03:42 2020 +0800
Merge branch 'change_site'
Conflicts:
test.txt
commit 14b4dcadbdc847207651d5a9fae0d315057f346e
Author: admin
Date: Sun Mar 1 14:53:15 2015 +0800
git tag
可以使用 git tag 給打上標簽
git reset HEAD
命令用于取消快取已快取的內容,
$ git status -s
M README
M hello.php
$ git add .
$ git status -s
M README
M hello.pp
$ git reset HEAD -- hello.php
Unstaged changes after reset:
M hello.php
$ git status -s
M README
M hello.php
git rm
將檔案從快取區中移除,
$ git rm hello.php
rm 'hello.php'
$ ls
README
git mv
命令做得所有事情就是 git rm --cached, 重命名磁盤上的檔案,然后再執行 git add 把新檔案添加到快取區,因此,雖然有 git mv 命令,但它有點多余 ,

分支的合并
場景:基于master分支的代碼,開發一個新的特性
如果你直接在master分支上開發這個新特性,是不好的,萬一你在開發特性1的時候,領導突然又要叫你去開發特性2,就不好處理了,難道開發的兩個特性都提交到master?一會兒提交特性1的commit,一會兒提交特性2的commit?這會導致commit記錄很混亂,
所以,我給你的建議做法是:給每個特性都單獨建一個的新的分支,
比如說,我專門給特性1建一個分支feature_item_recommend,具體做法如下:
(1)基于master分支,創建一個新的分支,起名為feature_item_recommend:
$ git checkout -b feature_item_recommend
Switched to a new branch 'feature_item_recommend'
上面這行命令,相當于:
$ git branch feature_item_recommend // 創建新的分支
$ git checkout feature_item_recommend //切換到新的分支
(2)在新的分支feature_item_recommend上,完成開發作業,并 commit 、push,
(3)將分支feature_item_recommend上的開發進度合并到master分支:
$ git checkout master //切換到master分支
$ git merge feature_item_recommend //將分支 feature_item_recommend 的開發進度合并到 master 分支
合并之后,master分支和feature_item_recommend分支會指向同一個位置,
(3)洗掉分支feature_item_recommend:
既然 特性1 開發完了,也放心地提交到master了,那我們就可以將這個分支洗掉了,
git branch -d feature_item_recommend
注意,我們當前是處于master分支的位置,來洗掉feature_item_recommend分支,如果當前是處于feature_item_recommend分支,是沒辦法洗掉它自己的,
同理,當我轉身去開發特性2的時候,也是采用同樣的步驟,
合并分支時,如果存在分叉

比如說上面這張圖中,最早的時候,master分支是位于C2節點,我基于C2節點,new出一個新的分支iss53,我在iss53上提交了好幾個commit,
現在,我準備把iss53上的幾個commit合并到master上,此時發現,master分支已經前進到C4了,那該怎么合并呢?
合并的命令仍然是:
$ git checkout master
$ git merge iss53
解釋:
這次合并的實作,并不同于簡單的并入方式,這一次,我的開發歷史是從更早的地方開始分叉的,
由于當前 master 分支所指向的commit (C4)并非想要并入分支(iss53)的直接祖先,Git 不得不進行一些處理,就此例而言,Git 會用兩個分支的末端(C4 和C5)和它們的共同祖先(C2)進行一次簡單的三方合并計算,
Git 沒有簡單地把分支指標右移,而是對三方合并的結果作一新的快照,并自動創建一個指向它的commit(C6)(如下圖所示),我們把這個特殊的commit 稱作合并提交(mergecommit),因為它的祖先不止一個,
值得一提的是Git 可以自己裁決哪個共同祖先才是最佳合并基礎;這和CVS 或Subversion(1.5 以后的版本)不同,它們需要開發者手工指定合并基礎,所以此特性讓Git 的合并操作比其他系統都要簡單不少,

解決合并時發生的沖突

如果 feature1和feature2修改的是同一個檔案中代碼的同一個位置,那么,把feature1合并到feature2時,就會產生沖突,這個沖突需要人工解決,步驟如下:
(1)手動修改檔案:手動修改沖突的那個檔案,決定到底要用哪個分支的代碼,
(2)git add:解決好沖突后,輸入git status,會提示Unmerged paths,這個時候,輸入git add即可,表示:修改沖突成功,加入暫存區,
(3)git commit 提交,
然后,我們可以繼續把 feature1 分支合并到 master分支,最后洗掉feature1、feature2,
注意:兩個分支的同一個檔案的不同地方合并時,git會自動合并,不會產生沖突,
比如分支feture1對index.html原來的第二行之前加入了一段代碼,
分支feature2對index.html在原來的最后一行的后面加入了一段代碼,
這個時候在對兩個分支合并,git不會產生沖突,因為兩個分支是修改同一檔案的不同位置,
git自動合并成功,不管是git自動合并成功,還是在人工解決沖突下合并成功,提交之前,都要對代碼進行測驗,
日常操作積累
修改密碼(曲線救國)
網上查了很久,沒找到答案,最終,在cld童鞋的提示下,采取如下方式進行曲線救國,
# 設定當前倉庫的用戶名為空
git config user.name ""
然后,當我們再輸入git pull等命令列時,就會被要求重新輸入新的賬號密碼,此時,密碼就可以修改成功了,最后,我們還要輸入如下命令,還原當前倉庫的用戶名:
git config user.name "smyhvae"
修改已經push的某次commit的作者資訊
已經push的記錄,如果要修改作者資訊的話,只能 通過--force命令,
將 branch1的某個commit1合并到branch2當中
切換到branch2中,然后執行如下命令:
git cherry-pick commit1
20200118-修改GitHub已提交的用戶名和郵箱
在執行./email.sh后,如果出現permission denied的錯誤,可以先執行chmod 777 email.sh,修改檔案的權限,
20200520-將Git 專案遷移到另一個倉庫
我們假設舊倉庫的專案名稱叫old-repository,新倉庫的專案名稱叫new-repository,操作如下:
(1)創建舊倉庫的裸克隆:
git clone --bare https://github.com/exampleuser/old-repository.git
執行上述命令后,會在本地生成一個名叫 old-repository.git的檔案夾,
(2)遷移到新倉庫:
cd old-repository.git
git push --mirror https://github.com/exampleuser/new-repository.git
這樣的話,專案就已經遷移到新倉庫了,
注意,我們不需要手動新建一個空的新倉庫,當我們執行上述命令之后,新倉庫就已經自動創建好了,
參考鏈接:
-
復制倉庫
-
Git 本地倉庫和裸倉庫
Git 服務器搭建
我們將以 Centos 為例搭建 Git 服務器,
1、安裝Git
$ yum install curl-devel expat-devel gettext-devel openssl-devel zlib-devel perl-devel
$ yum install git
創建一個git用戶組和用戶,用來運行git服務:
$ groupadd git
$ adduser git -g git
2、創建證書登錄
收集所有需要登錄的用戶的公鑰,公鑰位于id_rsa.pub檔案中,把我們的公鑰匯入到/home/git/.ssh/authorized_keys檔案里,一行一個,如果沒有該檔案創建它:
$ cd /home/git/
$ mkdir .ssh
$ chmod 700 .ssh
$ touch .ssh/authorized_keys
$ chmod 600 .ssh/authorized_keys
3、初始化Git倉庫
首先我們選定一個目錄作為Git倉庫,假定是/home/gitrepo/hello.git,在/home/gitrepo目錄下輸入命令:
$ cd /home
$ mkdir gitrepo
$ chown git:git gitrepo/
$ cd gitrepo
$ git init --bare hello.git
Initialized empty Git repository in /home/gitrepo/hello.git/
以上命令Git創建一個空倉庫,服務器上的Git倉庫通常都以.git結尾,然后,把倉庫所屬用戶改為git:
$ chown -R git:git w3cschoolcn.git
4、克隆倉庫
$ git clone [email protected]:/home/gitrepo/w3cschoolcn.git
Cloning into 'w3cschoolcn'...
warning: You appear to have cloned an empty repository.
Checking connectivity... done.
192.168.45.4 為 Git 所在服務器 ip ,你需要將其修改為你自己的 Git 服務 ip,這樣我們的 Git 服務器安裝就完成了,接下來我們可以禁用 git 用戶通過shell登錄,可以通過編輯/etc/passwd檔案完成,找到類似下面的一行:
git:x:503:503::/home/git:/bin/bash
改為:git:x:503:503::/home/git:/sbin/nologin
Git客戶端推薦
TortoiseGit
對這只小烏龜估計沒有開發人員會不認識,SVN的超廣泛使用也使得這個超好用的Svn客戶端成了幾乎每個開發人員的桌面必備軟體,小烏龜只提供Windows版本,提供中文版支持的,對于中國的開發者來說者絕對是福音,
小烏龜的檔案管理器右鍵選單的操作方式對于新手來說非常的容易上手,而且容易理解,
TortoiseGit(git客戶端工具)
Sublime Merge for Mac(git客戶端工具)
擁有簡潔的界面,三向合并工具,強大搜索功能,語法突出顯示等特點,Sublime Merge for Mac是一款Git客戶端工具,完成了Sublime,與Sublime Text的制造商會面,一個快速的用戶界面,三向合并工具,并排差異,語法高亮等等,Stage Files,iSwiftHunks和Lines沒有等待 – Sublime Merge真的非常非常快,
Sublime Merge for Mac(git客戶端工具)
GitHub for Desktop
全球開發人員交友俱樂部提供的強大工具,功能完善,使用方便,對于使用GitHub的開發人員來說是非常便捷的工具,界面干凈,用起來非常順手,上面的這條timeline非常漂亮,也可以直接提交PR,
唯一讓我失望的是GitHub for Desktop不帶三方合并工具,你必須自己手動解決沖突才可以,– 免費
– 同時支持 Windows 和 Mac:對于需要經常在不同的作業系統間切換的開發人員來說非常方便,
– 漂亮的界面:作為每天盯著看的工具,顏值是非常重要的
– 支持Pull Request:直接從客戶端提交PR,很方便
– Timeline 支持:直接在時間線上顯示每次提交的時間點和大小
– 支持git LFS:存盤大檔案更加節省空間和高效
– 不支持三方合并:需要借助第三方工具才行
Source Tree
SourceTree是老牌的Git GUI管理工具了,也號稱是最好用的Git GUI工具,我的體驗是確實強大,功能豐富,基本操作和高級操作都設計得非常流暢,適合初學者上手,
這個工具很有特色的一個功能就是支持Git Flow,你可以一鍵創建Git Flow的作業流,Git Flow是非常高效的團隊協作模型和流程,Git的一大特色就是靈活輕量的分支,但如何在自己的團隊中用好這個功能來匹配自己的研發流程是個問題,內置Git Flow讓那些不太熟悉的開發人員也可以很快上手,并且將研發的業務流程固化在工具中,可以說是非常貼心的設計,
Source Tree(git客戶端工具)
SmartGit:
商業用途收費, 個人用戶免費:
推薦書籍
- 《pro.git中文版》
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/190824.html
標籤:JavaScript
