我的git與github學習歷程


因為想要知道如何把代碼放到github上,所以就百度了一下,然后找到一個《 如何從github上面拷貝源碼》的文章,就先進行練習了下
 
1.首先到git官網下載git版本控制工具的安裝包,下載好雙擊安裝,所有的步驟我都默認的。

 


 

 

2.然后安裝完成我把沒打勾的地方都打勾了,然后點擊完成就出現如下圖藍色網頁和黑色彈框,藍色網頁的網址: file:///D:/Program%20Files/Git/ReleaseNotes.html

 

看到這些的時候我都不知道該怎么操作
 
然后百度了下git教程
 
根據教程學習
創建版本庫(即倉庫)
可以簡單理解成一個目錄,這個目錄里面的所有文件都可以被Git管理起來,每個文件的修改、刪除,Git都能跟蹤,以便任何時刻都可以追蹤歷史,或者在將來某個時刻可以“還原”。
d命令用於顯示當前目錄。在我的電腦上,這個倉庫位於。通過命令把這個目錄變成Git可以管理的倉庫
下面是創建版本倉庫的步驟:
在learngit目錄下(子目錄也可以)創建一個readme.txt文件。內容隨便。
然后使用命令 git add readme.txt 把文件添加到倉庫,執行之后沒有任何顯示就對了,然后使用命令 git commit -m "my first commit" 把文件提交到倉庫 -m后面是本次提交的說明,可以是任意內容。可以幫助你從歷史紀錄里找到改動記錄
 
git add命令可以多次使用
 
成功添加並提交readme.txt文件之后,我們將readme.txt文件的內容修改下,然后使用git status(可以查看倉庫當前的狀態)命令看下結果,結果如下:
結果告訴我們readme.txt被修改過但還沒有准備提交。我們可以使用 git diff這個命令查看修改了什么內容
從圖中可以看出我們將紅字中的four改成了綠色文字中的six。知道對readme.txt文件做了什么修改后,就可以放心提交到倉庫了。提交修改和提交新文件是一樣的兩步。
 
如果我們不想要最新修改的文件,想要回到之前的版本。我們可以先使用 git log 查看版本修改的歷史紀錄
git log 命令顯示從最近到最遠的提交日志,如果覺得輸出信息太多,可以使用 git log --pretty=oneline
 
需要友情提示的是,你看到的一大串類似的是(版本號),和SVN不一樣,Git的不是1,2,3……遞增的數字,而是一個SHA1計算出來的一個非常大的數字,用十六進制表示,而且你看到的和我的肯定不一樣,以你自己的為准。為什么需要用這么一大串數字表示呢?因為Git是分布式的版本控制系統,后面我們還要研究多人在同一個版本庫里工作,如果大家都用1,2,3……作為版本號,那肯定就沖突了。
 
使用git log命令之后我們就知道我們有哪些版本記錄了,然后我們將readme.txt回退到上一個版本。在Git中,用HEAD表示當前版本,也就是最新的版本,上一個版本是HEAD^,上上一個版本就是HEAD^^,當然往上100個版本寫100個^比較多,所以寫成現在使用命令將readme.txt回退到上一個版本: 
 
然后使用git log 查看版本庫的狀態,最新的版本已經看不到了。
如果我們還想回到最新的版本怎么做呢?我們只要知道最新版的版本號就可以了。然后使用
git reset --hard 版本號前幾位 就可以回到未來的某個版本
cat readme.txt查看readme.txt的內容 已經回到了最新版本

 

但是如果你已經關閉了git的命令窗口,不能往回查看版本號了,怎么辦呢?我們還有一個命令可以查看commit id 就是git reflog命令,它記錄了你的每一次命令。

總結:
1.HEAD指向的版本就是當前版本,因此,Git允許我們在版本的歷史之間穿梭,使用命令 git reset --hard commit_id。
2.穿梭前,用git log 可以查看提交歷史,以便確定要回退到哪個版本。
3.要重返未來,用git reflog 查看命令歷史,以便確定要回到未來的哪個版本。


學到版本回退時不知道怎么進入git倉庫,問了下同學寫如下命令即可 cd 后面是git倉庫的路徑,如果忘記git倉庫的路徑,可以使用pwd命令查看路徑

工作區和暫存區
前面講了我們把文件往Git版本庫里添加的時候,是分兩步執行的:
第一步是用把文件添加進去,實際上就是把文件修改添加到暫存區;
第二步是用提交更改,實際上就是把暫存區的所有內容提交到當前分支。
 
先實踐一下:先對readme.txt做個修改,然后在工作區添加一個LICENSE文本文件,內容隨便寫
 
然后使用git status命令查看下狀態
Git非常清楚地告訴我們,readme.txt被修改了,而LICENSE還從來沒有被添加過,所以它的狀態是Untracked。

現在,使用兩次命令git add,把readme.txt和LICENSE都添加后,用git status再查看一下:

現在所有的文件都放到了暫存區了,然后執行git commit 就可以一次性把暫存區的所有修改都提交到分支。
一旦提交后,如果你對工作區沒有任何修改,那么工作區就是干凈的。

管理修改
了解Git是如何跟蹤修改的,每次修改,如果不add到暫存區,那就不會加入到commit中。

撤銷修改
小結
場景1:當你改亂了工作區某個文件的內容,想直接丟棄工作區的修改時,用命令git checkout -- file。

場景2:當你不但改亂了工作區某個文件的內容,還添加到了暫存區時,想丟棄修改,分兩步,第一步用命令git reset HEAD file,就回到了場景1,第二步按場景1操作。
場景3:已經提交了不合適的修改到版本庫時,想要撤銷本次提交,參考版本回退一節,不過前提是沒有推送到遠程庫。

刪除文件
新建一個test文件,內容隨便,然后添加到Git並提交
如果在工作區將test文件刪掉了或者使用rm命令刪了,git status會告訴你哪些文件刪了

如果確實要刪除就使用git rm命令並且git commit

如果刪錯了,想要恢復就使用git checkout

 

遠程倉庫
github就是一個免費的遠程倉庫,不過需要先注冊哦!
第1步:創建SSH Key。在用戶主目錄下,看看有沒有.ssh目錄,如果有,再看看這個目錄下有沒有id_rsa和id_rsa.pub這兩個文件,如果已經有了,可直接跳到下一步。如果沒有,打開Shell(Windows下打開Git Bash),創建SSH Key:

這個是一路回車什么都沒設置的

如果一切順利的話,可以在用戶主目錄里找到.ssh目錄,里面有id_rsa和id_rsa.pub兩個文件,這兩個就是SSH Key的秘鑰對,id_rsa是私鑰,不能泄露出去,id_rsa.pub是公鑰,可以放心地告訴任何人。
第2步:登陸GitHub,打開“Account settings”,“SSH Keys”頁面:
然后,點“Add SSH Key”,填上任意Title,在Key文本框里粘貼id_rsa.pub文件的內容:

 

 
點擊add SSH key

添加遠程庫
現在的情景是,你已經在本地創建了一個Git倉庫后,又想在GitHub創建一個Git倉庫,並且讓這兩個倉庫進行遠程同步,這樣,GitHub上的倉庫既可以作為備份,又可以讓其他人通過該倉庫來協作,真是一舉多得。
首先,登陸GitHub,然后,在右上角找到“New repository”按鈕,創建一個新的倉庫,只需要填寫Repository name,其他默認即可,我這里填的learngit

點擊create repository,就成功創建了一個新的git 倉庫
 

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

請千萬注意,把上面的luojiao123替換成你自己的GitHub賬戶名,否則,你在本地關聯的就是我的遠程庫,關聯沒有問題,但是你以后推送是推不上去的,因為你的SSH Key公鑰不在我的賬戶列表中。
添加后,遠程庫的名字就是origin,這是Git默認的叫法,也可以改成別的,但是origin這個名字一看就知道是遠程庫。

下一步,就可以把本地庫的所有內容推送到遠程庫上:

把本地庫的內容推送到遠程,用git push命令,實際上是把當前分支master推送到遠程。
由於遠程庫是空的,我們第一次推送master分支時,加上了-u參數,Git不但會把本地的master分支內容推送的遠程新的master分支,還會把本地的master分支和遠程的master分支關聯起來,在以后的推送或者拉取時就可以簡化命令。
推送成功后,可以立刻在GitHub頁面中看到遠程庫的內容已經和本地一模一樣:

 

 

從現在起,只要本地作了提交,就可以通過命令:
$ git push origin master

把本地master分支的最新修改推送至GitHub,現在,你就擁有了真正的分布式版本庫!

小結
要關聯一個遠程庫,使用命令git remote add origin git@server-name:path/repo-name.git;
關聯后,使用命令git push -u origin master第一次推送master分支的所有內容;
此后,每次本地提交后,只要有必要,就可以使用命令git push origin master推送最新修改;
分布式版本系統的最大好處之一是在本地工作完全不需要考慮遠程庫的存在,也就是有沒有聯網都可以正常工作,而SVN在沒有聯網的時候是拒絕干活的!當有網絡的時候,再把本地提交推送一下就完成了同步,真是太方便了!


從遠程庫克隆
上次我們講了先有本地庫,后有遠程庫的時候,如何關聯遠程庫。
現在,假設我們從零開發,那么最好的方式是先創建遠程庫,然后,從遠程庫克隆。
首先,登陸GitHub,創建一個新的倉庫,名字叫gitskills:

 

 我們勾選Initialize this repository with a README,這樣GitHub會自動為我們創建一個README.md文件。創建完畢后,可以看到README.md文件:
 

現在,遠程庫已經准備好了,下一步是用命令git clone克隆一個本地庫:

 

 

然后到本地git目錄查看gitskills文件里面已經有readme.txt文件了
如果有多個人協作開發,那么每個人各自從遠程克隆一份就可以了。
你也許還注意到,GitHub給出的地址不止一個,還可以用https://github.com/michaelliao/gitskills.git這樣的地址。實際上,Git支持多種協議,默認的git://使用ssh,但也可以使用https等其他協議。
使用https除了速度慢以外,還有個最大的麻煩是每次推送都必須輸入口令,但是在某些只開放http端口的公司內部就無法使用ssh協議而只能用https。

創建與合並分支
創建dev分支,然后切換到dev分支

git checkout命令加上-b參數表示創建並切換,相當於以下兩條命令:
$ git branch dev
$ git checkout dev

然后使用git branch命令查看當前分支

git branch命令會列出所有分支,當前分支前面會標一個*號。
然后,我們就可以在dev分支上正常提交,比如對readme.txt做個修改,加上一行:
Creating a new branch is quick.
然后提交

現在dev分支完成,我們就可以切換回master分支

切換回master分支后,再查看一個readme.txt文件,剛才添加的內容不見了!因為那個提交是在dev分支上,而master分支此刻的提交點並沒有變:
現在,我們把dev分支的工作成果合並到master分支上:

git merge命令用於合並指定分支到當前分支。合並后,再查看readme.txt的內容,就可以看到,和dev分支的最新提交是完全一樣的。
注意到上面的Fast-forward信息,Git告訴我們,這次合並是“快進模式”,也就是直接把master指向dev的當前提交,所以合並速度非常快。
當然,也不是每次合並都能Fast-forward
合並完成后,就可以放心地刪除dev分支了:

刪除后,查看branch,就只剩下master分支了:

小結:
Git鼓勵大量使用分支:
查看分支:git branch
創建分支:git branch <name>
切換分支:git checkout <name>
創建+切換分支:git checkout -b <name>
合並某分支到當前分支:git merge <name>
刪除分支:git branch -d <name>

解決分支合並的沖突
准備新的feature1分支,繼續我們的新分支開發:

修改readme.txt最后一行,改為:
Creating a new branch is quick AND simple.

在feature1分支上提交:

切換到master分支

Git還會自動提示我們當前master分支比遠程的master分支要超前1個提交。
在master分支上把readme.txt文件的最后一行改為:
Creating a new branch is quick & simple.
提交

這時主分支和featurel分支修改的內容不一致,有沖突,當我們合並的時候就合並不了。

Git告訴我們,readme.txt文件存在沖突,必須手動解決沖突后再提交。git status也可以告訴我們沖突的文件:

我們可以直接查看readme.txt的內容,里面有沖突的顯示,我們修改如下后保存:
Creating a new branch is quick and simple.

再提交:

用帶參數的git log也可以看到分支的合並情況 --graph查看分支合並圖:

最后,刪除feature1分支:

工作完成。

分支管理策略
合並分支時,如果可能,Git會用Fast forward模式,但這種模式下,刪除分支后,會丟掉分支信息。
如果要強制禁用Fast forward模式,Git就會在merge時生成一個新的commit,這樣,從分支歷史上就可以看出分支信息。
下面我們實戰一下--no-ff方式的git merge:
首先,仍然創建並切換dev分支:

修改readme.txt文件,然后提交一個新的commit

 

現在我們切換回master
 
准備合並dev分支,請注意--no-ff參數,表示禁用Fast forward:
 

因為本次合並要創建一個新的commit,所以加上-m參數,把commit描述寫進去。
合並后,我們用git log看看分支歷史:

多人協作
使用git remote顯示詳細信息,我的gitskils文件夾里的git倉庫是連接遠程github的

推送分支,就是把該分支上的所有本地提交推送到遠程庫。推送時,要指定本地分支,這樣,Git就會把該分支推送到遠程庫對應的遠程分支上:
 
如果要推送其他分支,比如dev,就寫成

但是,並不是一定要把本地分支往遠程推送,那么,哪些分支需要推送,哪些不需要呢?
● master分支是主分支,因此要時刻與遠程同步;
● dev分支是開發分支,團隊所有成員都需要在上面工作,所以也需要與遠程同步;
● bug分支只用於在本地修復bug,就沒必要推到遠程了,除非老板要看看你每周到底修復了幾個bug;
● feature分支是否推到遠程,取決於你是否和你的小伙伴合作在上面開發。
總之,就是在Git中,分支完全可以在本地自己藏着玩,是否推送,視你的心情而定!

抓取分支
多人協作時,大家都會往master和dev分支上推送各自的修改。
現在,模擬一個你的小伙伴,可以在另一台電腦(注意要把SSH Key添加到GitHub)或者同一台電腦的另一個目錄下克隆:

小結
● 查看遠程庫信息,使用git remote -v;
● 本地新建的分支如果不推送到遠程,對其他人就是不可見的;
● 從本地推送分支,使用git push origin branch-name,如果推送失敗,先用git pull抓取遠程的新提交;
● 在本地創建和遠程分支對應的分支,使用git checkout -b branch-name origin/branch-name,本地和遠程分支的名稱最好一致;
● 建立本地分支和遠程分支的關聯,如果git pull提示“no tracking information”,則說明本地分支和遠程分支的鏈接關系沒有創建,用命令git branch --set-upstream branch-name origin/branch-name。
● 從遠程抓取分支,使用git pull,如果有沖突,要先處理沖突。

在Git中打標簽非常簡單,首先,切換到需要打標簽的分支上:
$ git branch
* dev
master
$ git checkout master
Switched to branch 'master'

然后,敲命令git tag <name>就可以打一個新標簽:
$ git tag v1.0

可以用命令git tag查看所有標簽:
$ git tag
v1.0

默認標簽是打在最新提交的commit上的。有時候,如果忘了打標簽,比如,現在已經是周五了,但應該在周一打的標簽沒有打,怎么辦?
方法是找到歷史提交的commit id,然后打上就可以了:
$ git log --pretty=oneline --abbrev-commit
6a5819e merged bug fix 101
cc17032 fix bug 101
7825a50 merge with no-ff
6224937 add merge
59bc1cb conflict fixed
400b400 & simple
75a857c AND simple
fec145a branch test
d17efd8 remove test.txt
...

比方說要對add merge這次提交打標簽,它對應的commit id是6224937,敲入命令:
$ git tag v0.9 6224937

再用命令git tag查看標簽:
$ git tag
v0.9
v1.0

注意,標簽不是按時間順序列出,而是按字母排序的。可以用git show <tagname>查看標簽信息:
$ git show v0.9
commit 622493706ab447b6bb37e4e2a2f276a20fed2ab4
Author: Michael Liao <askxuefeng@gmail.com>
Date: Thu Aug 22 11:22:08 2013 +0800

add merge
...

可以看到,v0.9確實打在add merge這次提交上。
還可以創建帶有說明的標簽,用-a指定標簽名,-m指定說明文字:
$ git tag -a v0.1 -m "version 0.1 released" 3628164

用命令git show <tagname>可以看到說明文字:
$ git show v0.1
tag v0.1
Tagger: Michael Liao <askxuefeng@gmail.com>
Date: Mon Aug 26 07:28:11 2013 +0800

version 0.1 released

commit 3628164fb26d48395383f8f31179f24e0882e1e0
Author: Michael Liao <askxuefeng@gmail.com>
Date: Tue Aug 20 15:11:49 2013 +0800

append GPL

還可以通過-s用私鑰簽名一個標簽:
$ git tag -s v0.2 -m "signed version 0.2 released" fec145a

簽名采用PGP簽名,因此,必須首先安裝gpg(GnuPG),如果沒有找到gpg,或者沒有gpg密鑰對,就會報錯:
gpg: signing failed: secret key not available
error: gpg failed to sign the data
error: unable to sign the tag

如果報錯,請參考GnuPG幫助文檔配置Key。
用命令git show <tagname>可以看到PGP簽名信息:
$ git show v0.2
tag v0.2
Tagger: Michael Liao <askxuefeng@gmail.com>
Date: Mon Aug 26 07:28:33 2013 +0800

signed version 0.2 released
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.12 (Darwin)

iQEcBAABAgAGBQJSGpMhAAoJEPUxHyDAhBpT4QQIAKeHfR3bo...
-----END PGP SIGNATURE-----

commit fec145accd63cdc9ed95a2f557ea0658a2a6537f
Author: Michael Liao <askxuefeng@gmail.com>
Date: Thu Aug 22 10:37:30 2013 +0800

branch test


如果標簽打錯了,也可以刪除:
$ git tag -d v0.1
Deleted tag 'v0.1' (was e078af9)

因為創建的標簽都只存儲在本地,不會自動推送到遠程。所以,打錯的標簽可以在本地安全刪除。
如果要推送某個標簽到遠程,使用命令git push origin <tagname>:
$ git push origin v1.0
Total 0 (delta 0), reused 0 (delta 0)
To git@github.com:michaelliao/learngit.git
* [new tag] v1.0 -> v1.0

或者,一次性推送全部尚未推送到遠程的本地標簽:
$ git push origin --tags
Counting objects: 1, done.
Writing objects: 100% (1/1), 554 bytes, done.
Total 1 (delta 0), reused 0 (delta 0)
To git@github.com:michaelliao/learngit.git
* [new tag] v0.2 -> v0.2
* [new tag] v0.9 -> v0.9

如果標簽已經推送到遠程,要刪除遠程標簽就麻煩一點,先從本地刪除:
$ git tag -d v0.9
Deleted tag 'v0.9' (was 6224937)

然后,從遠程刪除。刪除命令也是push,但是格式如下:
$ git push origin :refs/tags/v0.9
To git@github.com:michaelliao/learngit.git
- [deleted] v0.9

小結
● 命令git push origin <tagname>可以推送一個本地標簽;
● 命令git push origin --tags可以推送全部未推送過的本地標簽;
● 命令git tag -d <tagname>可以刪除一個本地標簽;
● 命令git push origin :refs/tags/<tagname>可以刪除一個遠程標簽。


配置別名
告訴Git,以后st就表示status:$ git config --global alias.st status

好了,現在敲git st看看效果。
當然還有別的命令可以簡寫,很多人都用co表示checkout,ci表示commit,br表示branch:
$ git config --global alias.co checkout
$ git config --global alias.ci commit
$ git config --global alias.br branch

以后提交就可以簡寫成:
$ git ci -m "bala bala bala..."

--global參數是全局參數,也就是這些命令在這台電腦的所有Git倉庫下都有用。
在撤銷修改一節中,我們知道,命令git reset HEAD file可以把暫存區的修改撤銷掉(unstage),重新放回工作區。既然是一個unstage操作,就可以配置一個unstage別名:
$ git config --global alias.unstage 'reset HEAD'

當你敲入命令:
$ git unstage test.py

實際上Git執行的是:
$ git reset HEAD test.py

配置一個git last,讓其顯示最后一次提交信息:
$ git config --global alias.last 'log -1'

這樣,用git last就能顯示最近一次的提交:
$ git last
commit adca45d317e6d8a4b23f9811c3d7b7f0f180bfe2
Merge: bd6ae48 291bea8
Author: Michael Liao <askxuefeng@gmail.com>
Date: Thu Aug 22 22:49:22 2013 +0800

merge & fix hello.py

甚至還有人喪心病狂地把lg配置成了:
git config --global alias.lg "log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit"

來看看git lg的效果:

 


為什么不早點告訴我?別激動,咱不是為了多記幾個英文單詞嘛!
配置文件
配置Git的時候,加上--global是針對當前用戶起作用的,如果不加,那只針對當前的倉庫起作用。
配置文件放哪了?每個倉庫的Git配置文件都放在.git/config文件中:
$ cat .git/config
[core]
repositoryformatversion = 0
filemode = true
bare = false
logallrefupdates = true
ignorecase = true
precomposeunicode = true
[remote "origin"]
url = git@github.com:michaelliao/learngit.git
fetch = +refs/heads/*:refs/remotes/origin/*
[branch "master"]
remote = origin
merge = refs/heads/master
[alias]
last = log -1

別名就在[alias]后面,要刪除別名,直接把對應的行刪掉即可。
而當前用戶的Git配置文件放在用戶主目錄下的一個隱藏文件.gitconfig中:
$ cat .gitconfig
[alias]
co = checkout
ci = commit
br = branch
st = status
[user]
name = Your Name
email = your@email.com

配置別名也可以直接修改這個文件,如果改錯了,可以刪掉文件重新通過命令配置。

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM