1. 程式人生 > >過來人告訴你,去工作前最好還是學學Git

過來人告訴你,去工作前最好還是學學Git

## 前言 > 只有光頭才能變強。 > **文字已收錄至我的GitHub精選文章,歡迎Star**:[https://github.com/ZhongFuCheng3y/3y](https://github.com/ZhongFuCheng3y/3y) 之前遇到過很多同學私信問我:「三歪,我馬上要實習了,我要在實習前學些什麼做準備啊?」 三歪在實習之前也同樣問過自己當時的部門老大。 如果再給我一次機會,我會先去花點時間去學學**Git**。 Git我相信大家對它應該不陌生吧?但凡用過GitHub的同學應該多多少少都會了解一下Git 不知道當時大家學Git的時候是看哪個教程的,我看的是廖雪峰老師的Git系列的。 (別看到廖雪峰就以為是廣告了啊,哈哈哈哈,這篇純原創分享) ![](https://tva1.sinaimg.cn/large/007S8ZIlgy1gfd41k2b77j32o40p6tly.jpg) ## 分享一下三歪的經歷 剛實習的時候,一直都忙著看各種東西。有一天,我學長說:我看你也學了一些基礎了,我們來看看公司的程式碼吧,看看我們生產環境是怎麼做的。 於是我學長丟了一個Git連結給三歪 ```git https://github.com/ZhongFuCheng3y/3y.git ``` 那三歪做了什麼?三歪去IDEA下把這個Git給Clone下來: ![](https://tva1.sinaimg.cn/large/007S8ZIlgy1gfd48yd39lj314e0i8457.jpg) 我用Clone完了以後,我學長又補了一句:這個專案不是用master分支的哦,你切換一下**分支**。 三歪:啥?切換分支?咋整?我忘了。 我學長看了下我,貌似不咋會切換分支,就說:“我來吧”。 於是在命令列終端一頓操作後,對三歪說:“好了” 三歪:“我對Git不是很熟悉,之前一直都是在IDEA上操作的。你們一般用命令列多還是圖形介面的多呀?” 我學長:“這沒什麼,反正工具這東西,學學就行,不是什麼大問題。也沒必要說很仔細去學它,就工具嘛” 三歪:“嗯” 時間飛逝,又過了一段時間... 三歪被分配了一個需求,於是就需要**新建分支**去做這個需求了。所有的**標準應用**線上走的是master分支,公司通過一個**釋出系統**來控制釋出版本、以及整套上下線的流程。 ![](https://tva1.sinaimg.cn/large/007S8ZIlgy1gfieefw9i2j31pt0u0wns.jpg) 於是我要先在釋出系統裡邊新建Git分支: ![](https://tva1.sinaimg.cn/large/007S8ZIlgy1gfiefuv4e0j30rs0pgtbn.jpg) 完了以後,我就在**IDEA介面上**選擇那個被我新建完的分支 ![](https://tva1.sinaimg.cn/large/007S8ZIlgy1gfiehc3z9tj30ns0haq5g.jpg) 但發現我死活找不到...於是我就問我學長:我在釋出系統裡邊新建了分支,為什麼在IDEA上找不到啊? 學長:“怎麼會呢,我看看”。 找了一會,他問我:“你fetch 過了嗎?” 三歪:“啥?” 於是他拿著我的電腦,打開了終端,又以是命令列的方式敲了一頓,問我:“這是不是你新建的分支?“ 三歪點了點頭,於是我學長說:”好了,你再看看“。 後來發現,新建完遠端分支,如果在IDEA上要能感知到,可以在`pull`介面上重新整理一下,那就能找到了。 ![](https://tva1.sinaimg.cn/large/007S8ZIlgy1gfiemwnospj312i0m2775.jpg) 也不是說命令列一定會就比介面牛逼,其實IDEA的Git功能也做得挺好的。現在我都是**混合**使用,一些操作用命令列,一些操作用IDEA快捷鍵。 我`commit`和`push`的時候就喜歡用快捷鍵。`command+k和command +shift+k`我就感覺比敲命令要快不少。 這些都是個人習慣的問題,也無對錯之分,怎麼方便怎麼來。 其實也不是所有的系統都會走釋出系統的(有標準應用,非標準應用)。如果要自己寫一個**啟動的指令碼**,一般我們會做些什麼?無非就是用`Git`拉最新的程式碼,然後用maven打個包,然後啟動。 ![](https://tva1.sinaimg.cn/large/007S8ZIlgy1gfe98dx1jej30ho05i0t8.jpg) ## 理解Git 如果你看過上一篇《[三歪給女朋友講解什麼是Git](https://mp.weixin.qq.com/s?__biz=MzI4Njg5MDA5NA==&mid=2247489082&idx=1&sn=dbdd2e6f59c4fac19fbbbb1870d2ca93&chksm=ebd7573bdca0de2d0d5556d2c652df5de7e66dbb137c878c026efbad319cc5cafdc3b8700aa5&token=1038232507&lang=zh_CN#rd)》應該能大概瞭解什麼是Git了。 其實我覺得學Git主要理解`工作區` -> `暫存區`->`倉庫` 這幾個概念。 ![](https://tva1.sinaimg.cn/large/007S8ZIlly1gfrxg2chesj30k003xdfu.jpg) 我們使用Git其實**絕大部分**的操作都是在**本地**上完成的,比如說`add 和commit`。 只有我們`push`的時候,才會把本地完成好的內容推到**遠端倉庫**上 通過上一篇文章我們知道在每個人的本地都有**完整的歷史版本**,所以我們可以在本地就能**穿梭**到不同的版本,然後將修改之後的程式碼再重新提交到遠端倉庫上。 所謂的工作區實際上就是我們真正的的**本地目錄**。 我們在本地新增檔案後,需要`add`到暫存區,檔案一旦被`add`到了暫存區,意味著Git能`追蹤`到這個檔案。 當我們修改到一定程度之後,我們會執行一次提交`commit`,在提交的時候我們會”**備註**“自己這次的提交修改了什麼內容。 一次`commit`在Git就是一個版本,Git是版本控制的軟體,我們可以隨意穿梭到任何的版本中,修改程式碼。 暫存區是這麼一個概念呢? > 暫存區就像購物車,沒到付款的時候你都不確定購物車裡的東西全部都是要的。每拿一件商品就付一次款,那麻煩可大了。 從巨集觀上看,Git其實有本地和遠端的概念,只是本地又分了工作區、暫存區、本地倉庫。再次強調:我們操作幾乎都是在本地完成,**每個人的本地都會有所有歷史版本資訊**。 ![](https://tva1.sinaimg.cn/large/007S8ZIlly1gfryz5w84pj310x0bc3zc.jpg) 我們一般會新建**分支**去支援每一次的修改。 其實分支這個概念也挺好理解的:我們需要**並行**開發,同時我們又不關心對方改的是什麼內容,改的是什麼檔案。因此我們需要在自己的**專屬環境**下去修改內容,只要把最終修改完後的內容合併到一個**主分支**就OK了。 ![](https://tva1.sinaimg.cn/large/007S8ZIlly1gfs27mnamkj30uy0dg75z.jpg) 假設三歪做完了,經過校驗通過後,把自己的程式碼`merge`(合併)到`origin/master`分支後,然後就釋出上線啦。 隨後,雞蛋也做完了,自己的分支校驗完了以後,他此時也想把自己的程式碼合併到`origin/master`。不料,他改的程式碼跟三歪改的程式碼有衝突了(Git不知道選擇誰的的程式碼),那雞蛋只能手動`merge`了。 綜合來看,我們使用Git大多數的場景就是**各自分支開發**,然後各自在本地`commit`(提交),最後彙總到`master`分支。 ![](https://tva1.sinaimg.cn/large/007S8ZIlly1gfs3zyhapvj31040eg0u5.jpg) 所以,我們學Git大多數就學怎麼實現**分支的增刪改、切換以及版本的穿梭**。 > 學習Git的小tips: > Unix/Linux 命令中,`-` 後一般跟短命令選項(通常是單字母,也有一些命令是例外的),`--` 後一般跟長命令選項。如果只有一個單獨的`--`,後面不緊跟任何選項,則表示命令選項結束,後續的都作為命令的引數而不是選項。 > 例如:`git checkout -- filename` `filename`作為`git checkout` 的引數,而不是選項。 ## 日常Git使用場景 **一**、如果這個專案的程式碼我們在本地還沒有,我們先去GitLab裡邊找對應的Git地址,然後**Clone**到本地: ```shell git clone https://github.com/ZhongFuCheng3y/3y.git ``` ![](https://tva1.sinaimg.cn/large/007S8ZIlgy1gfim3xmd2vj30qz08cwgc.jpg) **二**、接到了新的需求,我們要**新建**一個分支,然後基於這個分支去開發: ```shell git checkout -b feature/sanwaiAddLog ``` 在開發的時候,我們肯定會有兩個操作: - 在原來的基礎上新增新的檔案 - 在原有的檔案上修改 **三**、不管怎麼樣,等我們做到一定程度了,我們都會提交程式碼。如果我們添加了新的檔案,我們需要先`add`,然後再`commit` ```shell git add . git commit -m "try to commit files to GitHub, i am java3y" ``` **四**、假設我們一切順利,在沒人打擾的情況下已經寫好了程式碼了,然後我們會把自己的分支`push`到遠端倉庫 ```java git push ``` **五**、假設我們寫到一半,其他小夥伴已經把他的程式碼`merge`到主分支了,我們也需要把他最新的 程式碼給`pull`拉取下來(可以 git fetch + git merge 替代)。 ``` git pull ``` 如果沒有衝突,那git就會把他的程式碼給`merge`到我當前的分支上。如果有衝突,Git會提醒我去手動解決一下衝突。 **六**、假設我們寫到一半了,現在工作區的程式碼都已經`commit`了。此時同事說要不幫忙一起排查一個問題,同事一般用的是**自己分支**,於是就得問他:你用的哪個分支啊?於是得把他的分支給拉下來,看看他的程式碼哪兒有問題 ```shell git fecth -- 手動拉取遠端倉庫更新的資訊 git checkout 分支名 -- 切換到他的分支 ``` 現在切換到他的分支,相當於你的環境跟他的環境是一模一樣的,於是就可以愉快地一起看Bug了。 **七**、假設我們寫到一半了,現在工作區的程式碼還沒`commit`。現在有同事說要排查問題或者一個新的Bug被發現了,要緊急切換到其他的分支。現在我又不想`commit`(我就寫了一半,編譯還報著錯誤,沒理由讓我`commit`吧)。 這時,我會把工作區的程式碼先`stash`到暫存區給儲存起來,然後就可以愉快地切換其他的分支了。 ```git git stash ``` 等我解決完另一個bug或者幫別人看完問題了,我再把剛剛儲存在暫存區的程式碼給撈出來,繼續幹活 ``` git stash pop ``` **八**、我一直在修Bug,現在的分支已經被我搞得人摸鬼樣了,我非常難受,甚至不知道自己在這個過程中改了多少東西了。 ![](https://tva1.sinaimg.cn/large/007S8ZIlly1gfs4pn7qf1j31g00a6wh0.jpg) 思路已經完全被打亂了,我想回到一個穩定的`commit`重新出發,重來吧(通過下面的命令,把工作區的程式碼都改成對應commit的程式碼了)。 ```shell git reset --hard 版本號 ``` 那我怎麼找到版本號呢?Git也是有日誌的: ```shell git log --pretty=oneline ``` ![](https://tva1.sinaimg.cn/large/007S8ZIlly1gfs4ukl52gj31h405zwhb.jpg) ## 常用的Git命令 檢視Git工作區、暫存區的變更情況(可以知道哪些沒有commit、哪些沒有被Git追蹤):`git status` 拉取遠端最新的變更到本地:`git fetch` 切換分支:`git checkout 分支名` 將程式碼還原到某個版本(包括工作目錄):`git reset --hard 版本號 ` 檢視Git的提交(commit)記錄:`git log` 將程式碼還原到某個版本後,後悔了,想重新回去,但在提交記錄已經找不到了。`git reset --hard ` 把`reset 之後的 commit`都給抹殺掉了。找到最近的執行Git命令:`git reflog` 還原到某個版本了,現在我為了穩健,不想再原來的分支上修改了,再**新建一個分支**吧(`-b` 引數把當前分支切換到了要建立的分支上):`git checkout -b 分支名` 我們把上一次還是”相對穩健“的分支合併到我新建的分支上:`git merge 分支` 突然想看看現在有多少個分支:`git branch -a` 新增幾個檔案了,隨手`git add`一下吧 改得差不多了,隨手`git commit -m `一下吧,最好還是**寫好備註**,不然以後等改多了,你都不知道你改了什麼啦。 改完了,提交到遠端吧:`git push ` 想把遠端分支最新的程式碼給拉下來,然後合併到本地上。我們可以用`git fetch`和`git merge `來實現,也可以通過`git pull`來實現。一般我用的都是`git fetch`+`git merge `,這樣會更加**可控**一些 有的時候,本地分支在master分支,然後忘了切其他的分支去修改,直接在master改了,然後也push到遠端了。等你發現的時候,你會真的想罵自己。 咋辦?最簡單的辦法其實我們還是可以`git reset --hard`到對應的版本,然後將其修改或者復原,再強制提交到`master`分支:`git push -u origin/master -f` ![](https://tva1.sinaimg.cn/large/007S8ZIlly1gfuiuhjr4sj30dw08o3ys.jpg) ## 三歪瞎扯 在這篇文章中,我列出的Git常用的命令其實並不多吧。 像很多部落格講的`diff`、`tag`、`config`之類的命令我都沒有講,我這邊**現實開發時**這些命令也沒怎麼用過... **如果覺得我說漏的,可以在評論區補充,一起學習。** 其實現在`IDEA`也很強大,很多時候都可以配合`IDEA`給我們提供的`Git`去做很多事。有的場景敲命令會比較方便,有的時候就直接圖形化介面就比較方便。 就`diff `這個功能而言, 肯定還是圖形介面好用一些吧(至少我是這樣認為的 IDEA配合一些快捷鍵,使用Git也能爽得飛起。Git始終也只是一個工具,如果你有興趣可以瞭解它的實現(我覺得大部分人可能不知道它是怎麼實現的); 如果沒興趣看它的實現,瞭解它是怎麼使用的,也**足夠**應付日常的開發場景了。 總的來說,現在的網際網路公司大多數還是用Git的,Git本身使用上其實不難,只要理解了Git是幹嘛的,它有個本地倉庫的概念,它可以來回穿梭各種版本,然後將本地的資訊提交到遠端,跟著教程把常用的命令敲敲也差不多了。 如果實在是不懂,也別慌(我都給你們打了個樣了);主動認慫,虛心求教,同事們都不會嫌棄你的。 如果實習之前不知道要準備什麼去公司,要是對Git不瞭解,我覺得Git可以有佔一席之位。 **更多Git命令**和參考資料: - [https://github.com/xjh22222228/git-manual](https://github.com/xjh22222228/git-manual) - [https://juejin.im/post/5edcf3a36fb9a047fa04fbc3](https://juejin.im/post/5edcf3a36fb9a047fa04fbc3) - [https://www.liaoxuefeng.com/wiki/896043488029600](https://www.liaoxuefeng.com/wiki/896043488029600) ## 各類知識點總結 > 下面的文章都有對應的**原創精美**PDF,在持續更新中,可以來找我催更~ - [92頁的Mybatis](https://mp.weixin.qq.com/s/0_zTBooRV4RTWQa8VOwiWg) - [129頁的多執行緒](https://mp.weixin.qq.com/s/r7IrmvBxG5W0hswfcgFjcQ) - [141頁的Servlet](https://mp.weixin.qq.com/s?__biz=MzI4Njg5MDA5NA==&mid=2247486798&idx=1&sn=ce900e97a495ffd681cd0ad9b78aa5ca&chksm=ebd74c4fdca0c559d0a32a3f3ddb3f579d3a16b47f70234c46ac2e5df315e7df90f93d1715b9&token=1109491988&lang=zh_CN#rd) - [158頁的JSP](https://mp.weixin.qq.com/s?__biz=MzI4Njg5MDA5NA==&mid=2247486854&idx=1&sn=fd77a6225b898b69c4f0e1a7e66cf105&chksm=ebd74c87dca0c5910a923a443ea6f694dd554b68df8cc00506570555b9cf7718a2ef2a058754&token=1109491988&lang=zh_CN#rd) - [76頁的集合](https://mp.weixin.qq.com/s?__biz=MzI4Njg5MDA5NA==&mid=2247486873&idx=1&sn=ce0752f481336ffba9b8f44265b2550e&chksm=ebd74c98dca0c58ee04162d7e5d07fd36c8ec1b32460a8a2396168a9fc5885a208810f0916f2&token=1109491988&lang=zh_CN#rd) - [64頁的JDBC](https://mp.weixin.qq.com/s?__biz=MzI4Njg5MDA5NA==&mid=2247486905&idx=1&sn=67fcd0558cfbdf6cd36de98cbd93afaf&chksm=ebd74cb8dca0c5ae052e6d216ed13458a9a17fa1b0f245bf740379b1d4b04b4e55fcbfb5adb4&token=1109491988&lang=zh_CN#rd) - [105頁的資料結構和演算法](https://mp.weixin.qq.com/s?__biz=MzI4Njg5MDA5NA==&mid=2247486831&idx=1&sn=0d4b05e10d66eda1129f43348a8e3952&chksm=ebd74c6edca0c5786a5109a131d0501ef6bd02077e5ce1ad75d906cf3612a320d1098163e2d0&token=1109491988&lang=zh_CN#rd) - [142頁的Spring](https://mp.weixin.qq.com/s?__biz=MzI4Njg5MDA5NA==&mid=2247487013&idx=1&sn=f0d8c292738eb49bcd09cb2f6458dc69&chksm=ebd74f24dca0c632fa3ef8f205a2dd5c96531f78a68eae805e15b84de0b59774196a188aed14&token=306734573&lang=zh_CN#rd) - [58頁的過濾器和監聽器](https://mp.weixin.qq.com/s?__biz=MzI4Njg5MDA5NA==&mid=2247487054&idx=1&sn=25f92798050d092027931e2ae0379e90&chksm=ebd74f4fdca0c6595bc795fd00354cf683d4593550cdd38ba7103893dd622606fc8f55fe6631&token=306734573&lang=zh_CN#rd) - [30頁的HTTP](https://mp.weixin.qq.com/s?__biz=MzI4Njg5MDA5NA==&mid=2247487071&idx=1&sn=511459730b3114fc77c60b82b54159b8&chksm=ebd74f5edca0c648c9b0c572fbc7fdbc26179ddcd7c45de37c06b6a2906a8ffc207f145b66f2&token=480724592&lang=zh_CN#rd) - [42頁的SpringMVC](https://mp.weixin.qq.com/s?__biz=MzI4Njg5MDA5NA==&mid=2247487665&idx=1&sn=cffb9d634a8b770562557b72a833e591&chksm=ebd751b0dca0d8a604d89b1e3c5d1728f35b752368f5a878311066cbc09ff8a5905ad05690c7&token=634601022&lang=zh_CN#rd) - Hibernate - AJAX - Redis - ...... #### 涵蓋Java後端所有知識點的開源專案(已有8K+ star): - [GitHub](https://github.com/ZhongFuCheng3y/3y) - [Gitee訪問更快](https://gitee.com/zhongfucheng/Java3y) **我是三歪,一個想要變強的男人,感謝大家的點贊收藏和轉發,下期見。給三歪點個贊,對三歪真的非常重