--- tags: Coding --- # git ## 安裝 ``` brew install git ``` ## 忽略掉檔案 防止不必要的檔案被測到  ```bash= #設定git信箱跟名子 git config --global user.email 電子信箱 git config --global user.name 你的名子 #檢查giy信箱與名子 git config --global user.email git config --global user.name ``` ## 基本指令 ```bash= #看git狀態 git status # 如果還沒初始化 # 致命錯誤: 不是一個 git 版本庫(或者任何父目錄):.git 初始化 git init ``` ```bash= #加入檔案到緩衝區 git add 檔案 #加入路徑下所有檔案 git add . ``` 加完會被放在上面綠色緩衝的地方  之後有更改也會顯示  ```bash= #把綠色緩衝區的檔案提交 git commit -m "first save" ``` 綠色的不見了 被記錄了  ```bash= #存擋紀錄 如果下面有冒號可以按q離開 git log ```  ## 重置檔案 ```bash= #取消被add進去緩衝區的檔案 git reset 檔案 #取消所有被add進去緩衝區的檔案 git reset . ``` ```bash= #取消前一個的commit 但至少要有兩個commit存在 #head後面是要往前幾個 --soft是軟執行 --hard是強制執行 git reset --soft head~1 ```  連git log也會不見 ```bash= #回復被更改的檔案 到上次的commit 但在緩衝區的不受影響 #法一 git restore test.py #法二 git checkout -- 檔案 ```  ```bash= #回復到指定存擋點 後面像亂碼的是要恢復存擋點的編碼 #沒有用雲端保存的話 回復前的存擋點會消失 git reset f936f22342d095f65f2cece6c17a6eb5c33b2313 #查看存擋點做的改變 git show f936f22342d095f65f2cece6c17a6eb5c33b2313 ```  ## 連接到github ```bach= #連上要上傳的git repostories #後面網址是資料庫的位置 origi是源頭名稱 #token跟名稱要問gpt git remote add origin https://使用者名稱/token @github.com/Bruce762/gittest.git #看資料庫有什麼分支 git remote #master線上的存擋點上傳到github中的original #加 -u可以在下次上傳時只打push就好 git push -u origin master #用HEAD代表當前所在的線 就不用看現在在哪條 git push -u origin HEAD #把資料庫中的東西下載下來 #之前的上傳紀錄什麼的也都可以看到 git clone https://github.com/Bruce762/gittest.git ``` git remote add origin出現錯誤時 ```bash= git remote add origin https://github.com/Bruce762/code.git 錯誤: 遠端 origin 已經存在。 ``` 移除舊的origin ```bash= git remote remove origin ``` 添加新的origin ```bash= git remote add origin https://github.com/Bruce762/code.git ``` 資料庫位置  第一條主線叫做master  ## 更新最新資料 git fetch 只下載最新的更新,但不會自動將變更合併到你的本地分支。 git pull 則是 git fetch 後接著自動合併變更,相當於 git fetch 加上 git merge。 ```bash= git fetch git pull ``` ```bash= #把github上最新的進度拉下來 #與其他人的push完發生衝突也要用pull拉下來 git pull #但pull conflict要用下面兩種方式 #法ㄧ 會列出衝突的地方 如下圖 git merge --no-ff #法二 直接把新的存擋接到github的最後面 不建議在共用分支上使用 git rebase ``` Accept Crrent change 保留綠色 Accept incoming change 保留藍色 Accept Both change 保留兩個 Compare changes 開一個視窗幫你比較  ## branch ```bash= #查看自己在哪個支線 git branch #創建新支線 git branch 支線名稱 #刪除本地支線 但不能刪自己所在的支線 git branch -d branch-name # 安全刪除(已合併) git branch -D branch-name # 強制刪除 #刪除遠端支線 git push origin --delete branch-name ```  ```bash= #切換支線 #法一 git checkout 支線名稱 #法二 git switch 支線名稱 #創建支線並切換過去 git checkout -b 支線名稱 #切換回切換前的支線 git checkout - ```  ```bash= #合併支線 把要合併的支線內容加到目前所在的支線 並且解決衝突 #所以名子是目前支線 但內容是合併的支線的內容 git merge 合併的支線 ```  ### 本地與遠端分支 **查看目前 Git 專案所在的本地分支:** ```bash git branch ``` 輸出: 有星號 `*` 的那一行表示你目前所在的分支。 ``` * main develop feature/login ``` **查看目前分支對應的遠端分支:** ```bash git branch -vv ``` 輸出 ``` * feature/login abc1234 [origin/feature/login] 登入功能完成 main def5678 [origin/main] 初始版本 ``` **查看所有的遠端分支:** ```bash git branch -r ``` 輸出 ``` origin/HEAD -> origin/main origin/feature/login origin/main ``` ## 不小心push錯 現在雲端的9是不小心push錯的  ```bash= #硬重置 git reset --hard HEAD~1 #-f強制推送 git push -f origin <branch-name> ``` ## branch合併 假設有主線(master)與支線(second)  master主線  second支線(還未push)  假如直接push支線的話  github上會有合併請求(pull request) 右上角綠色的  或是先到second支線 上面會出現contribute可以pull request  但上面會有can't auto merge代表衝突所以沒辦法合併  ### 法一:先rebase再push給github 請求pull quest(merge) 推薦 可以看到有誰pull request(推薦) 所以要用rebase把支線接到主線的屁股上  先切到主線上pull到最新進度 然後切回支線做rebase接到master後面 ```bash= git switch master git pull git switch second git rebase master #把目前所處的線接到master線上 記得緩衝區不能有東西 git rebase origin/master #另一種寫法 ```  但可能會遇到衝突  解完衝突commit之後 要用下面指令 只是有時候會有復數衝突 要做比較多次 ```bash= git rebase --continue ```` 可以看到second的東西被接到master後面了  push只能上傳到原有基礎上的最新存擋點 但因為git log中存擋點的位置都改變了 就要用`-f`強制上傳 不然會出錯 但因為會改到整個git log 所以要小心使用 ```bash= git push -f ```  這個時候就可以提出合併請求了  經過比較後新的有完全包含舊的才行  管理者同意合併請求後 切回master 然後用pull更新會長這樣 ```bash= git switch master git pull ```  #### 就算pull request成功 只要別人或其他檔案有先push或merge 就要再解決conflict second支線狀態(rebase完的)  在master還沒push前 先把second做pull request  然後push master  結果發生conflict  還是要再切到second去解決conflict  解決完conflict push後就可以merge了  ### 法二:先在自己的電腦上merge然後再push 不推薦 但比較不建議法二 主要是別人看不到自己的pull request 因為自己merge好的檔案可能 在雲端上有其他人先存擋了 可能又要多處理conflict 假如上面進度 master新增func5  second新增func4  先切到master 之後git merge ```bash= git switch master git merge second #把second加到master做merge ``` ```bash= #如果merge發生衝突之後要手動git commit的話 git commit #會跑出文字編輯 要用:wq進行存擋 或:x!確認合併 #如果打成:q!會跳出去而沒有存擋 ``` 最後解決完衝突之後就可以push到github 但可能其他人先push檔案了 就要再解一次conflict  ### 比較rebase merge 法ㄧ比較可以看到 pull request相較於法二來說比較清楚好溝通 rebase通常在支線上執行 merge在主線上 **merge commit:** git merge 會保留合併的歷史,顯示兩個分支如何交互,並會生成一個新的合併提交,這使得 Git 記錄中會出現一個分支合併的節點。這對於團隊協作來說能夠反映多個開發分支的歷史過程。 ``` ---B---C (main) \ D---E (feature) ``` 當 feature 合併進 main 之後,結果會變成: ``` A---B---C---M (main) \ / D---E (feature) ``` **rebase:** git rebase 則會重新排列提交歷史,讓結果看起來像是一條線性歷史。這會使提交記錄更乾淨,但是原始的分支歷史(例如衝突解決的過程)會被覆蓋。 ``` A---B---C (main) \ D---E (feature) ``` 當 feature 重整到 main 之後,結果會變成: ``` A---B---C---D'---E' (main 和 feature) ``` * merge 的適用場景: * 適合 團隊協作 中,保留分支的完整歷史紀錄與合併過程,能夠直觀反映分支的交互過程。 * 在多個開發人員並行開發的情況下,保留合併提交能幫助追蹤問題和變更源頭。 * rebase 的適用場景: * 適合個人開發者或想保持提交歷史乾淨的情況下使用,以保持提交歷史的線性結構。 * 在處理長期存在的功能分支時,常用 rebase 來與主分支保持同步,而不引入大量的合併提交。 * 當需要提交歷史保持簡潔和整齊時,rebase 是一個很好的選擇,但需要謹慎使用,特別是避免在共享的分支上進行 rebase,因為會改變歷史,可能導致他人無法正常更新代碼。 ## 如果沒有git檔案又有衝突的情況 ```bash git clone 最新的檔案 git checkout HEAD~1 #回到前幾的檔案之前 ``` 用完改動並且commit之後 ```bash git switch -c fix-file #先把 detached HEAD 內容掛到一條新分支(fix-file) git push -u origin fix-file #推到遠端 ``` ## detached完commit後要合併回main ```swift # 建立一個臨時分支來保存目前的 commit git switch -c temp-save # 切回 main 分支 git switch main # 合併剛剛的 commit 到 main git merge temp-save # (選擇性)可以刪掉臨時分支 git branch -d temp-save ``` ## gitignore沒辦法忽略檔案的狀況 在项目开发过程中个,一般都会添加 .gitignore 文件,规则很简单,但有时会发现,规则不生效。 原因是 .gitignore 只能忽略那些原来没有被track的文件,如果某些文件已经被纳入了版本管理中,则修改.gitignore是无效的。 那么解决方法就是先把本地缓存删除(改变成未track状态),然后再提交。 git rm -r --cached . 把所有檔案untrack 但如果是.DS_Store系統檔的話可能就要手動刪除 ```bash= git rm -r --cached . git add . git commit -m 'update .gitignore' git push ``` 在這個情境中,我們有兩個開發者 A 和 B,分別負責不同的部分:A 負責撰寫程式碼,B 負責撰寫測試碼。他們使用 VS Code 來開發 Java 程式,專案採用 Maven 架構,並且透過 Git 來進行版本控制。以下是具體的版控流程,描述如何進行協作和合併專案。 ## 情境範例 A 和 B 正在開發一個簡單的計算器應用程式,A 主要負責開發程式邏輯,而 B 負責編寫單元測試。兩人透過 GitHub 進行協作,並希望確保每個人的工作在相互獨立的分支上進行,最後再合併到主分支(`main`)。 ### Git 協作流程 1. **設定 GitHub Repo** - A 在 GitHub 上建立一個新的 Maven 專案 Repo,並邀請 B 參與專案。 - A 將此 Repo 克隆到本地: ```bash git clone https://github.com/username/project.git ``` 2. **建立分支** - 為了保持分工明確,A 和 B 各自建立自己的工作分支。 - A 建立了一個名為 `feature/calculator-logic` 的分支,負責撰寫程式邏輯: ```bash git checkout -b feature/calculator-logic ``` - B 則建立了一個名為 `feature/test-cases` 的分支,用於撰寫測試代碼: ```bash git checkout -b feature/test-cases ``` 3. **A 開發程式邏輯** - A 在 `feature/calculator-logic` 分支中開發計算器的核心功能。完成後,A 將代碼提交並推送到遠端: ```bash git add . git commit -m "Add calculator logic" git push origin feature/calculator-logic ``` 4. **B 撰寫測試代碼** - B 切換到自己的分支 `feature/test-cases`,並開始撰寫測試代碼。B 可以通過拉取 A 的分支來獲取最新的程式邏輯: ```bash git fetch origin git checkout feature/calculator-logic git pull origin feature/calculator-logic ``` - 確認程式邏輯後,B 撰寫測試代碼,並推送到遠端: ```bash git checkout feature/test-cases git add . git commit -m "Add test cases for calculator" git push origin feature/test-cases ``` 5. **發送 Pull Request** - A 和 B 完成各自的工作後,將分支的變更推送到 GitHub,並發送 Pull Request。 - A 創建 PR 以將 `feature/calculator-logic` 分支合併到 `main`,B 則創建 PR 以將 `feature/test-cases` 分支合併到 `main`。 - 兩人可以在 GitHub 上進行相互代碼審查(Code Review),確保合併到 `main` 分支的代碼質量。 6. **合併分支** - 當代碼審查完成並確認沒有問題後,A 和 B 各自批准他們的 PR 並將分支合併到 `main`。 - 合併後,兩人將拉取最新的 `main` 分支: ```bash git checkout main git pull origin main ``` 7. **解決合併衝突(若有)** - 如果在合併時出現衝突,Git 會提示需要手動解決衝突。A 或 B 需要協調並解決這些衝突,然後重新提交合併。 8. **結束分支** - 分支合併後,A 和 B 可以選擇刪除各自的開發分支,以保持 Repo 的整潔: ```bash git branch -d feature/calculator-logic git branch -d feature/test-cases ```
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up