Git Workflow Summary: A Real-World Journey

Git 工作流程總結:一趟真實的實戰之旅

This is the story of your project, from a local folder to a fully managed GitHub repository.
這是你的專案故事,從一個本機資料夾,到一個功能完整的 GitHub 倉庫。


Phase 1: Project Initialization (Day 1)
第一階段:專案初始化 (第一天)

Goal: Get your local project onto GitHub for the first time.
目標: 首次將你的本機專案放到 GitHub 上。

Visual Overview
視覺化概覽

Local Folder → Git Repository → GitHub Repository
本機資料夾 → Git 倉庫 → GitHub 倉庫
  1. Prepare Your Folder:
    準備你的資料夾:
    You created photo_sorter_v2.py, README.md, and a crucial .gitignore file to exclude personal data and cache files.
    你建立了 photo_sorter_v2.pyREADME.md 和一個關鍵的 .gitignore 檔案,用來排除個人資料和快取檔案。Example .gitignore content:
    範例 .gitignore 內容:

    # Personal data folders
    photos_to_sort/
    people_folders/
    processed.txt
    
    # Python cache
    __pycache__/
    *.pyc
    
    # IDE files
    .vscode/
    .idea/
    
  2. Create a Remote Home:
    建立一個遠端的家:
    You went to GitHub.com and created a new, empty repository.
    你前往 GitHub.com 建立了一個新的、空的倉庫。
    💡 Pro Tip: Don’t initialize with README, .gitignore, or license when you already have local files.
    💡 專業提示: 當你已經有本機檔案時,不要初始化 README、.gitignore 或授權條款。
  3. Initialize Git Locally:
    在本機初始化 Git:
    git init
    將你的專案資料夾變成一個本機 Git 倉庫。
  4. Stage All Your Files:
    暫存所有檔案:
    git add .
    告訴 Git:「我想要將所有檔案都包含在下一個『存檔點』(提交)中。」
  5. Make Your First “Save”:
    進行你的首次「存檔」:
    git commit -m "Initial commit: Add photo sorter v2 with GUI interface"
    建立了你專案歷史中的第一個官方快照(提交)。
  6. Connect Local to Remote:
    將本機與遠端連接:
    git remote add origin https://github.com/yourusername/your-repo.git
    建立了一個名為 origin 的捷徑,指向你的倉庫網址。
  7. Upload Your Project:
    上傳你的專案:
    git push -u origin main
    首次將你的本機 main 分支推送到 origin 遠端。

Phase 2: The First Update & A “Remote Changed” Conflict
第二階段:首次更新與「遠端已變更」的衝突

Goal: Add a new feature and push the update.
目標: 新增一個功能並推送更新。

The Conflict Scenario
衝突情境

Local:  A → B → C (your new commit)
Remote: A → B → D (someone else's commit)
  1. Modify Your Code:
    修改你的程式碼:
    你編輯了你的 Python 腳本。與此同時,GitHub 上的 README.md 也被更改了。
  2. Attempt to Push (and Fail):
    嘗試推送 (但失敗了):
    git push
    你收到了 ! [rejected] (fetch first) 的錯誤。
    Git 正在保護你。GitHub 上有一個你本機還沒有的提交。
  3. The Solution: Sync Before Pushing:
    解決方案:推送前先同步:
    git pull origin main
    它嘗試從 GitHub 下載新的提交,並將其與你的本機工作合併。

Phase 3: Resolving Merge Conflicts
第三階段:解決合併衝突

Goal: Fix the issues that git pull uncovered so you can finally sync.
目標: 修復 git pull 發現的問題,以便你最終可以同步。

Scenario A: The “Uncommitted Changes” Conflict
情境 A:「未提交的變更」衝突

  1. The Problem: git pull 失敗,顯示 Your local changes would be overwritten by merge
  2. Reason: 你在本機修改了 README.md,但還沒有用 git commit 來儲存它。
  3. The Fix: 你先提交了你的本機工作。
    git add README.md
    git commit -m "Update README with new features"
    

Scenario B: The “Content” Conflict
情境 B:「內容」衝突

  1. The Problem: 提交後,再次 git pull,得到 CONFLICT (content): Merge conflict in README.md
  2. Reason: 你和遠端都在同一個檔案的相同幾行上,各自有了一個已提交的變更。
  3. The Fix (The Manual Merge):
    步驟 1:打開 README.md,看到衝突標記,然後編輯檔案使其內容正確。

    <<<<<<< HEAD
    你的本機變更
    =======
    來自 GitHub 的遠端變更
    >>>>>>> commit-hash
    

    步驟 2:git add README.md(告訴 Git 衝突已解決)
    步驟 3:git commit(完成合併,建立一個特別的「合併提交」)

Alternative: Using Git Stash
替代方案:使用 Git Stash

git stash
git pull origin main
git stash pop

Phase 4: The Final, Successful Push
第四階段:最終的成功推送

Goal: Upload your now-perfect local history to GitHub.
目標: 將你現在已臻完美的本機歷史紀錄上傳到 GitHub。

Local:  A → B → C → D → M (merge commit)
Remote: A → B → D
  1. The Final Command:
    git push origin main
  2. The Result: 成功!指令順利執行,因為你的本機歷史紀錄現在已經包含了遠端的歷史紀錄。

Phase 5: Making a Major Change with a Branch (Advanced)
第五階段:使用分支進行重大變更 (進階)

Goal: Replace the GUI with a new spreadsheet-based system without breaking the existing code.
目標: 用一個新的、基於試算表的系統來取代 GUI,同時不破壞現有的程式碼。

Branch Strategy Visualization
分支策略視覺化

main:               A → B → C → D → M ← (merge from feature)
                                 ↗
spreadsheet-sorter:         E → F → G
  1. Ensure You’re on main and Up-to-Date:
    git checkout main
    git pull origin main
    
  2. Create and Switch to a New Branch:
    git checkout -b spreadsheet-sorter
  3. Restructure Your Project:
    你刪除了舊的 GUI 腳本,建立了兩個新的試算表腳本,並更新了 README.md
  4. Commit the Changes to the New Branch:
    git add .
    git commit -m "Feat: Replace GUI with spreadsheet workflow"
    
  5. Push the New Branch to GitHub:
    git push -u origin spreadsheet-sorter
  6. (Optional) Merging Back to main:
    當你對新系統感到滿意時,透過 Pull Request 合併回 main 分支。
    合併後清理:

    git checkout main
    git pull origin main
    git branch -d spreadsheet-sorter
    

Git Rebase vs Merge
Git Rebase 與 Merge 的差異

  • Merge (Default): 建立合併提交,保留分支歷史
  • Rebase: 在目標分支上重新播放提交,建立線性歷史
    git checkout main
    git pull origin main
    git checkout spreadsheet-sorter
    git rebase main
    git checkout main
    git merge spreadsheet-sorter
    

The Core Git Loop
核心 Git 循環

你的所有經驗可以歸結為這個基本的日常工作流程:

Step Command Purpose
1. Pull git pull origin main Always start by syncing with the remote
永遠先從與遠端同步開始
2. Work (edit files) Make your changes, edit your code
進行你的修改,編輯你的程式碼
3. Stage git add . or git add <file> Add your changes
加入你的變更
4. Commit git commit -m "Clear message" Save your work with a clear message
用一則清晰的訊息來儲存你的工作
5. Push git push origin main Share your commits with the remote
將你的提交分享到遠端

Commit Message Best Practices
提交訊息最佳實踐

  • feat: Add subfolder scanning support
  • fix: Handle UTF-8 encoding in progress file
  • docs: Update README with installation guide
  • refactor: Simplify image loading logic

Bad commit messages: update, fix bug, changes


Troubleshooting Common Issues
常見問題排除

  • Issue 1: “Permission denied (publickey)”
    問題 1:「Permission denied (publickey)」
    解決方案:設定 SSH 金鑰或使用個人存取權杖的 HTTPS

    git remote -v
    git remote set-url origin https://github.com/username/repo.git
    
  • Issue 2: “fatal: not a git repository”
    問題 2:「fatal: not a git repository」
    解決方案:確保你在正確的目錄中並且已經執行了 git init
  • Issue 3: Large files causing push failures
    問題 3:大檔案導致推送失敗
    解決方案:使用 .gitignore 排除大檔案或使用 Git LFS

    *.mp4
    *.zip
    large_datasets/
    git lfs track "*.psd"
    git add .gitattributes
    

Advanced Tips for Azure and Cloud Development
Azure 和雲端開發的進階技巧

  • Integration with Azure DevOps
    與 Azure DevOps 整合

    1. Azure Repos:GitHub 的替代方案,具有整合的 CI/CD
    2. Azure Pipelines:當你推送到 main 時自動部署
    3. 分支政策:強制執行程式碼審查和測試
  • Git Hooks for Automation
    用於自動化的 Git Hooks

    #!/bin/sh
    python -m py_compile *.py
    if [ $? -ne 0 ]; then
        echo "Python syntax errors found. Commit aborted."
        exit 1
    fi