如何同步应用项目的两个分支:构建版框架与开发仓库
Alright, let's dig into this Git merge problem you're stuck with. So you've got two branches: one uses a Framework subproject for active development, the other ships a pre-built framework for third-party devs. Every time you merge, you're fighting those annoying "add/remove subproject" commits that you just want to ignore—no more manual cleanup every time. Here are four practical solutions that fit different scenarios:
1. Path-Specific Merge Strategies (Quick, No Fuss)
Git lets you apply custom merge rules to specific directories, which is perfect for ignoring changes to your framework/subproject folders entirely.
How to use it:
When merging your dev branch (with the subproject) into the third-party branch (pre-built framework), run this command to keep the third-party branch's state for both critical directories:
git merge dev-with-subproject -X ours:framework-subproject/ -X ours:built-framework/
- The
-X oursflag tells Git to stick with the current branch's (third-party) version of these directories. So if the dev branch tries to addframework-subproject/or removebuilt-framework/, Git will ignore those changes automatically. - Reverse the flags if merging from third-party back to dev: use
-X ours:built-framework/ -X ours:framework-subproject/to keep the dev branch's subproject intact.
If you want this to be semi-automatic, save a bash alias in your .bashrc or .zshrc:
alias merge-safe='git merge dev-with-subproject -X ours:framework-subproject/ -X ours:built-framework/'
Just run merge-safe next time you need to merge.
2. Cherry-Pick Only Relevant Commits (Precise Control)
If you want to avoid merging entire branches and instead pick only the commits that don't touch framework-related changes, this method gives you full control over what gets merged.
Step-by-step:
- First, list all commits on your dev branch that haven't been merged into the third-party branch:
git log --oneline third-party-release..dev-with-subproject - Filter out the annoying add/remove commits (adjust the grep pattern to match your actual commit messages):
git log --oneline third-party-release..dev-with-subproject | grep -v "remove subproject\|add framework" - Cherry-pick the remaining commit hashes (replace the example hashes with your own):
git cherry-pick abc123 def456 ghi789
Automate it with a script:
Save this as merge-safe.sh to skip manual filtering every time:
#!/bin/bash TARGET_BRANCH=$1 SOURCE_BRANCH=$2 # Grab commit hashes, excluding unwanted commit messages COMMITS=$(git log --format="%h" $TARGET_BRANCH..$SOURCE_BRANCH | grep -v -E "(remove subproject|add framework)") # Cherry-pick each valid commit for COMMIT in $COMMITS; do git cherry-pick $COMMIT done
Make it executable and run it:
chmod +x merge-safe.sh ./merge-safe.sh third-party-release dev-with-subproject
3. Rewrite History (Advanced, Team-Coordinated)
If those add/remove commits are pure clutter you want to eliminate for good (and your team is on board), you can rewrite the branch's history to exclude them entirely. Warning: This changes Git history, so only do this if everyone working on the repo is aware, and back up your code first.
How to do it:
- Get the hashes of the commits you want to remove (use
git logto find them). - Run this command, replacing the example hashes with your own:
git filter-branch --commit-filter ' if [ "$GIT_COMMIT" = "abc123" ] || [ "$GIT_COMMIT" = "def456" ]; then skip_commit "$@" else git commit-tree "$@" fi' HEAD
This will rewrite the current branch's history, stripping out those unwanted commits forever.
4. Git Submodules (Long-Term Structural Fix)
For a permanent solution that avoids the add/remove cycle entirely, restructure your project to use Git submodules for the Framework. This separates the framework's development from your app's code:
Setup steps:
- In your dev branch, add the Framework as a submodule (link it to its own repo for active development):
git submodule add https://your-framework-repo-url.git framework-subproject git commit -m "Add Framework as submodule for active development" - In your third-party branch, remove the submodule and add the pre-built framework files:
git rm framework-subproject # Copy your pre-built framework files into a folder like built-framework/ git add built-framework/ git commit -m "Add pre-built framework for third-party developers"
Now, when merging between branches, Git will treat the submodule and pre-built files as distinct entities. You can pair this with the path-specific merge strategy from method 1 to keep the correct version of each directory automatically.
内容的提问来源于stack exchange,提问作者Adamski




