使用git也有好久了,後來有一段時間一直沒有機會去使用,如今想來總結一下本身學習了這麼長時間的一些心得感悟,我寫的博客通常都是開了一個輪廓和框架,等到之後有所思有所悟了還會增長的,正如軟件同樣一直都會不斷地更新,加入新的東西,修改一些過期的東西,咱們作人和作事也應該這樣,不斷地學習新的知識,取其精華去其糟粕,不斷地進步和增加。關於git也是用來進行項目管理的,一樣是爲了團隊協做,這個場景使你們使用着各自的電腦,可能相隔萬里,只要可以進行通訊,就可以從github上進行代碼的同步操做,這是很是有意思的。git
相比於之前的subversion等項目管理軟件,git更加的強大,而且很好用,這裏的好用有兩種意思,第一是功能很強大,每個成員均可能將中心倉庫的代碼給刪除了,固然也能植入本身的內容,第二個好用是一不當心提交了錯誤的代碼一樣的也會被其餘成員所使用,形成很惡劣的影響。所以十分熟悉git的操做,明白背後的意義,以及合理的使用git來進行代碼的維護是很是重要的。上次咱們學習了maven是爲了管理依賴,統一風格,而git則是爲了同步代碼,管理項目的進程,這二者一個面向於代碼的同步和轉移,另外一個面向於項目內部的實現和依賴的處理,二者結合起來組成的開發能力就很是的強大了,對於團隊開發來講很是的重要,是兩把利劍。github
衆所周知,Git是一個軟件,安裝在本地的機器上,用來從Github這個遠程倉庫中pull、push代碼,從而達成團隊協做開發的目的。這二者就比如是抽水機和池塘,Git從GitHub之中獲得代碼而且維護着版本和分支的信息,從而進行合併和開發。所以使用Git必需要有Github帳號以及項目才行。shell
Git的安裝很是簡單,只須要從官網上下載並安裝就能夠了,不用配置什麼環境變量就可以進行使用了。一樣的官網上還提供了不少的GUI用來對Git得到的代碼進行分析和操做,咱們能夠大體瞭解一下。安裝的過程很簡單,咱們再也不贅述,安裝完成以後就能打開使用了。能夠看到這個shell使用的是Linux中的命令,很是的有意思。數據庫
接下來咱們在github上建立一個項目,放一些文件進去便於咱們的實驗。考慮到多人協做的問題,咱們先建立一個組織,在組織下面在建立項目,同時能夠邀請其餘人加入咱們的項目實現協同工做。數據結構
這樣咱們的項目就建好了,剩下的就是邀請其餘人進入其中,而且最好的就是將別人的公鑰放入本身的Github上去,這樣其餘人在使用Git的時候就不用每次都輸入帳戶和密碼了。在設置,SSH或者GPG祕鑰之中,咱們加入本身和別人的公鑰。可是須要注意的一點就是,咱們若是使用SSH加密的話,須要將項目改爲使用SSH可以獲取的,以後咱們在添加SSH祕鑰,這一點很是重要!!!!!!app
在Git中使用以下命令來生成祕鑰和公鑰:框架
ssh-keygen -t rsa -C 郵箱號
而後咱們轉到生成的公鑰和私鑰的目錄,私鑰是咱們本身的打死都不能給別人,而公鑰就是讓別人拿來給本身進行通訊的,所以,咱們把公鑰發給這個項目的管理員,讓他在剛剛的地方複製進去咱們的公鑰,這樣就能很好的工做了。eclipse
咱們能夠根據Git項目的網址將項目clone到本地,這個不須要祕鑰,可是若是之後提交內容的時候就須要了:ssh
好比咱們在這個時候不加入公鑰到倉庫之中,那麼咱們操做到了git push的時候就不能向下執行了,很是的麻煩,須要輸入帳號和密碼,而且以後仍是須要配置的。maven
那麼咱們將公鑰加入倉庫之中,此時管理員會收到郵件提醒,作的仍是很到位的:
而後咱們再從新下載一下項目,能夠看到項目加載成功!
對於clone下來的項目,開發就是按照以往的開發方法,將這些文件導入到myeclipse之中,可能使用了maven,那就更新依賴,以後就能夠進行開發了,那麼什麼叫作開發呢?!開發的本質其實就是增長文件、修改已有的文件、刪除某些文件,再說白一點就是對原來的文件庫進行增刪改操做,這就是開發,那麼由於這些操做必然會影響到咱們的本地倉庫之中的代碼,好比咱們增長了一個文件,又修改了一個文件,還刪除了一個文件,而後要怎麼樣同步到遠程倉庫之中呢,那就須要用到Git的強大功能了,另外提醒一點,在咱們使用git的時候必定要把myeclipse關閉了,否則由於其中某些文件沒保存,或者產生了一些臨時文件被咱們提交了就可能形成錯誤。
下面咱們模仿開發以後提交的過程:
首先,當咱們clone下來文件以後,第一件事是什麼呢?!絕對不是直接就開發了,而是將Git切換到這個目錄內部,而後新建一個分支,在新的分支上進行改動,這一點是重中之重,能夠防止咱們將原來的文件給修改了以後恢復不了的問題。在咱們的項目中默認只有一個主分支master,咱們在任什麼時候間不能在這個分支上進行任何的開發。
git checkout -b 分支名
這樣咱們進行的開發都是在這個新的分支上開發了,不會影響主分支的結果,好比咱們在新的分支上放入一個文件。
若是直接切換到主分支,此時由於沒有保存這個改變,咱們在主分支也能看到這個文件了,這是由於咱們在沒有保存這些改變到新分支上面的時候,這些文件只能算是文件系統上面的文件天然能被全部分支看見,其實對分支內部的數據結構來講是透明的。
可是咱們接下來在切換回新分支,而後保存以後在切換回主分支看看,這樣也解決了咱們的一個疑惑,若是隨便扔到分支裏面一個文件就要認可的話,那麼使用起來也太須要當心了。
上面咱們使用了:
git add . git commit -m "描述信息"
接下來咱們正式將開發好的新分支合併到主分支上面:
git checkout master git pull git checkout "新分支" git rebase -i master git checkout master git merge "新分支"
zyr@DESKTOP-RS2P5FV MINGW64 /d/GitTest (zyr_first) $ git checkout master Switched to branch 'master' Your branch is up to date with 'origin/master'. zyr@DESKTOP-RS2P5FV MINGW64 /d/GitTest (master) $ git pull Already up to date. zyr@DESKTOP-RS2P5FV MINGW64 /d/GitTest (master) $ git checkout zyr_first Switched to branch 'zyr_first' zyr@DESKTOP-RS2P5FV MINGW64 /d/GitTest (zyr_first) $ git rebase -i master Successfully rebased and updated refs/heads/zyr_first. zyr@DESKTOP-RS2P5FV MINGW64 /d/GitTest (zyr_first) $ git checkout master Switched to branch 'master' Your branch is up to date with 'origin/master'. zyr@DESKTOP-RS2P5FV MINGW64 /d/GitTest (master) $ git merge zyr_first Updating 4b1509b..313111a Fast-forward test1.txt | 1 + 1 file changed, 1 insertion(+) create mode 100644 test1.txt zyr@DESKTOP-RS2P5FV MINGW64 /d/GitTest (master) $ git push Enumerating objects: 4, done. Counting objects: 100% (4/4), done. Delta compression using up to 2 threads. Compressing objects: 100% (2/2), done. Writing objects: 100% (3/3), 331 bytes | 331.00 KiB/s, done. Total 3 (delta 0), reused 0 (delta 0) To github.com:zyrtest/GitTest.git 4b1509b..313111a master -> master zyr@DESKTOP-RS2P5FV MINGW64 /d/GitTest (master) $
咱們能夠看到新的改動已經成功的提交了。
咱們整理一下思路,首先新建一個分支(checkout -b),而後在新分支上面開發,以後將開發的內容綁定到新分支(add,commit),而後切換回主分支,使用pull命令將最新版本的項目再次下載下來,這一點是很是重要的,若是沒有這一步,其餘人可能在咱們下載、修改、到提交的這麼長的時間段已經將新的內容提交上去了,若是咱們直接將好久之前咱們下載的東西和咱們本身修改的東西結合到一塊兒提交的話使用push命令,可能形成不可挽回的結果,那就是其餘人在這個時間段提交的東西所有都沒有了,很容易被炒魷魚的~~~而後咱們再次切換回新分支,讓新分支掛載到master的基線上面(rebase),以後咱們再次切換回master,而後進行最終的合併,merge,最後咱們提交,其實這個時候咱們也是有必定風險的,假設在咱們push的同時,其餘人也在push,這個機率過小了,可是也有可能發生的,若是是這樣,總有一我的的會被刷掉,這樣某一方就須要從新下載最新的,合併以後而後提交了,可是開發團隊人比較少,這種機率小得幾乎不用考慮。
下面咱們總結一下整個流程,在這裏我使用操做來表達:
最後一步,很是重要,不能忘記!
這就是使用Git進行項目開發的幾個過程,須要注意:只有在提交的時候才能在master目錄,其他的狀況下都要在本身建立的分支中。
固然還有一些基本的設置:
git config --global user.email "郵件名稱" git config --global user.name "用戶名"
基本的查看命令:
git branch -a #查看全部分支 git remote -v #查看遠程倉庫
git status #查看分支提交狀態
git checkout #查看當前分支
一樣的還能使用別名:這樣能夠少寫不少東西,很是的方便。
git config --global alias.st status git config --global alias.co checkout git config --global alias.ci commit git config --global alias.br branch git config --global alias.unstage 'reset HEAD' # 撤銷暫存區的修改 git config --global alias.last 'log -1' # 顯示最後一次提交 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"
.gitignore文件
有些時候,咱們必須把某些文件放到Git工做目錄中,但又不能提交它們,好比保存了數據庫密碼的配置文件等等,這個問題解決起來也很簡單,在Git工做區的根目錄下建立一個特殊的.gitignore文件,而後把要忽略的文件名填進去,Git就會自動忽略這些文件。
忽略某些文件時,須要編寫.gitignore;網上已經有針對不一樣語言的ignore內容了,所以,咱們只用再加上本身的一些須要忽略的文件就能夠了。
.gitignore文件自己要放到版本庫裏,而且能夠對.gitignore作版本管理!
忽略文件的原則是:
一、忽略操做系統自動生成的文件,好比縮略圖等;
二、忽略編譯生成的中間文件、可執行文件等,也就是若是一個文件是經過另外一個文件自動生成的,那自動生成的文件就不必放進版本庫,好比Java編譯產生的.class文件;
三、忽略帶有敏感信息的配置文件,好比存放口令的配置文件。
忽略特定文件:.gitignore文件
git check-ignore -v 文件名
# 若是發現多是寫得有問題,須要找出來到底哪一個規則寫錯了,能夠用命令檢查.gitignoregit check-ignore
咱們新建一個文件叫作「.gitignore」,在文件裏寫上咱們不想提交可是又必須使用的那個文件,好比這裏我再建立一個文件:
而後咱們使用git status看一下,以後咱們發現發生改變的只有.gitignore,而沒有了咱們想要忽略的文件,這樣就等因而自動過濾掉了這個文件,而後咱們將發生改變的.gitignore文件上傳便可。
在這裏我直接在主分支上修改了,是一個很差的習慣,你們必定要新建一個分支再修改,否則可能會出現錯誤。
同時咱們也能查看是否將咱們的某些文件放到.gitignore裏面了:
查看不一樣: git diff # 查看工做區與倉庫的不一樣 git diff HEAD # 查看工做區與當前分支最新commit之間的差別 git diff <file> # 查看當前文件與倉庫文件的不一樣 git diff <commit_1>...<commit_2> # 查看兩次提交之間的差別 查看歷史記錄: git log -3 # 顯示過去3次提交 git log --pretty=oneline # 只顯示commit_id和提交註釋 git log --graph # 顯示爲分支合併圖 git log --abbrev-commit # 顯示縮略commit_id git log --stat # 顯示每次commit發生變動的文件 git log -S <keyword> # 根據關鍵詞搜索提交歷史 git log --follow <file> # 顯示文件的版本歷史,同 git whatchanged <file> git log -p <file> # 詳細列出與文件相關的每一次diff git reflog #查看每一次命令和操做
跳轉至指定版本(commit) HEAD 當前版本號,HEAD^ 上一個版本號,HEAD^^ 上上個版本號,HEAD~100 上一百個版本號 git reset --hard <commit_id>
撤銷修改: git checkout [<commit_id|branch|tag>] [--] <file> # 恢復版本庫的指定版本到工做區,省略commit_id則從暫存區進行恢復, #--用於避免commit_id|branch|tag與file重名 git reset HEAD <file> # 撤銷暫存區的修改
刪除文件: git rm <file> # 刪除工做區文件,並將此次刪除放入暫存區 git commit -m "delete an exist file" git rm --cached <file> # 中止追蹤指定文件,保留在工做區
文件更名: git mv <oldname> <newname> # 更名文件,並將此次更名放入暫存區 git commit -m "rename an file oldname to newname"
顯示指定版本(commit):
git show <commit_id> git show --name-only <commit_id> # 顯示某次提交發生變化的文件 git show <commit_id>:<file> # 顯示某次提交時,某個文件的內容
一、關聯本地庫與遠程庫,origin爲該遠程庫在本地的名稱 git remote add origin git@XXX.git git remote add origin https://github.com/XXX.git 2.將本地庫的內容推送到遠程庫 git push [-u] [--all] [--force] origin <local_b>:<remote_b> # 將本地local_b分支的更新推送到遠程庫origin的remote_b分支, # (-u)表示把二者關聯起來,同時指定origin爲默認主機, # (--all)表示推送本地全部分支, # (--force)表示強行推送,即便有衝突 git push origin <local_b> # 將本地local_b分支的更新推送到遠程庫origin的相同名稱分支,若是後者不存在則會被建立 git push origin :<remote_b> # 推送一個空的本地分支到遠程分支,等於刪除指定的遠程分支 git push origin # 將本地當前分支的更新推送到遠程庫origin中有追蹤關係的遠程分支 git push # 適用於當前分支只有一個追蹤分支的狀況,或指定默認主機的狀況 git push origin <tag_name> # 推送一個本地標籤到遠程庫 git push origin --tags # 推送所有未推送過的本地標籤 git push origin :refs/tags/<tag_name> # 刪除一個遠程標籤 3.克隆遠程庫到本地庫,自動關聯,且遠程庫的默認名稱爲origin git clone git@XXX.git git clone [-o origin] <addr> [local_dir_name] # 指定遠程庫名稱和本地目錄名稱 4.查看遠程庫 git remote git remote -v # 顯示遠程庫的地址,包括fetch和push地址 git remote show origin # 顯示遠程庫的詳細信息 git remote add origin git@XXX.git # 添加遠程庫 5.獲取遠程庫 git fetch # 更新全部遠程庫所包含分支的最新commit_id,並記錄到.git/FETCH_HEAD文件中 git fetch origin # 更新遠程庫origin的全部分支的最新commit git fetch origin <remote_b> # 更新遠程庫origin的remote_b分支 git fetch origin <remote_b>:<local_b> # 更新遠程庫origin的remote_b分支,並在本地建立local_b分支保存遠程分支的數據 git pull [--rebase] origin <remote_b>:<local_b> # 獲取遠程庫origin的remote_b分支的更新,而後與本地local_b分支合併 git pull origin <remote_b> # 獲取遠程庫origin的remote_b分支的更新,而後與本地當前分支合併 git pull origin # 獲取遠程庫origin中與本地當前分支有追蹤關係的遠程分支的更新,而後合併 git pull # 適用於當前分支只有一個追蹤分支的狀況 6.創建關聯/追蹤關係tracking git branch --set-upstream <local_b> origin/<remote_b> # 指定local_b分支追蹤origin/remote_b分支
分支: 1.建立分支 git branch <branch_name> [<start_point>] # 當指定start_point時,即爲當前分支的某一次commit來建立分支 2.切換分支 git checkout <branch_name> git checkout <commit_id> # 切換到某個commit,進入detached HEAD狀態 3.建立並切換分支 git checkout -b <branch_name> [<start_point>] # 等價於前兩步操做 4.查看分支 git branch # 查看本地分支,當前分支前面會標一個*號 git branch -r # 查看遠程分支 git branch -a # 查看全部分支 5.合併分支,合併模式:Fast-forward快進模式,優先使用,但刪除分支會丟失分支信息 git merge <branch_name> # 合併指定分支到當前分支 git merge --no-ff -m "merge with a new commit" <branch_name> # 強制禁用ff模式,merge時會生成一個新的commit git rebase [-i] <branch_name> # 將當前分支的commit取消掉,並臨時保存爲補丁, #而後把當前分支更新爲指定分支,最後把保存的補丁應用到該分支上,(-i)打開交互模式 git rebase --continue # 當有衝突並解決完成時,使用git-add命令更新,而後執行命令繼續應用餘下的補丁 git rebase --abort # 中斷合併並恢復 6.刪除分支 git branch -d <branch_name> git branch -D <branch_name> # 強行刪除一個未合併的分支 git branch -dr origin/<remote_b> # 刪除一個遠程分支 7.隱藏當前工做區的修改,便於建立bug分支 git stash # 隱藏 ...debug... git stash list # 查看隱藏內容列表 git stash apply [stash@{i}] # 恢復指定隱藏內容 git stash drop [stash@{i}] # 刪除指定隱藏內容 git stash pop [stash@{i}] # 恢復並刪除指定隱藏內容
這裏說一下stash,暫存工做區。咱們在已有的分支中,修改一個文件的部份內容,注意是修改,不是建立新的文件。若是咱們此時還沒完成這個分支的工做,可是必須跳到其餘分支去處理任務,咱們使用git stash暫存當前的修改,能夠看到工做樹又幹淨了,之前的修改不見了,又恢復到了沒修改以前的狀態,而後咱們跳到新的分支去繼續修改其餘的任務,當修改完畢以後,在新的分支上可能有保存和提交,以及最終push,而後咱們回到本分支,使用git stash pop命令就能夠恢復到以前的狀態了,而後繼續修改,最終提交便可。
標籤做用: 在開發的一些關鍵時期,使用標籤來記錄這些關鍵時刻, 例如發佈版本, 有重大修改, 升級的時候, 會使用標籤記錄這些時刻, 來永久標記項目中的關鍵歷史時刻;
標籤 1.建立標籤 git tag <tag_name> # 給當前分支的最新commit(即HEAD)建立標籤 git tag <tag_name> <commit_id/abbrev_commit_id> # 給指定commit 建立標籤 git tag -a <tag_name> -m "create a new tag on a commit" <commit_id/abbrev_commit_id> # 建立帶有說明的標籤 git tag -s <tag_name> -m "create a new tag on a commit" <commit_id/abbrev_commit_id> # 用PGP簽名標籤 2.查看標籤 git tag git show <tag_name> # 查看指定標籤 3.刪除標籤 git tag -d <tag_name>
git有不少操做,真正使用的其實也就那幾個,可是有的時候咱們的項目很是複雜,須要不少其它的功能的時候,這些看似不重要的功能就有用了,在學習的時候咱們實用便可,不須要掌握全部的操做,可是要可以稍微瞭解一下這些功能,在遇到複雜問題時可以去很好的解決,關於Git的說明就到這裏,基本上可以知足咱們開發的須要。
參考文獻:https://blog.csdn.net/q449560173/article/details/65628261