Git发布分支文件详情、父分支查询及未合并文件验证技术咨询
Great question! Let's break this down into two clear parts: enhancing your git log output to include filename and parent branch details, and optimizing your workflow to check for unmerged changes in those YYYYMM-named feature/fix branches.
1. Adding Filename and Parent Branch Info to Git Log Output
Your existing git log command gives you core commit details, but we can extend it to include the filename and the source branch (where the commit originated before merging into your release branch). Here's how to do it with a bash loop:
Step-by-Step Implementation
# Define your release branch name (update this to match your repo) RELEASE_BRANCH="main" for filename in $(git ls-files); do # Extract basic commit details, including the commit ID commit_details=$(git log -1 --source --date=format:"%Y-%m-%d" --all --pretty="%h|%an|%ad|%s" "$filename") commit_id=$(echo "$commit_details" | cut -d'|' -f1) # Try to find the parent/source branch (for merge commits) # We target the second parent of merge commits (since first parent is the release branch) parent_branch=$(git branch --contains "$commit_id^2" 2>/dev/null | grep -E '^[* ] [0-9]{6}$' | sed 's/^[* ] //' | head -n1) # Handle non-merge commits (direct commits to release branch) if [ -z "$parent_branch" ]; then parent_branch="N/A (direct commit to $RELEASE_BRANCH)" fi # Assemble the final output with filename and parent branch echo "~|$commit_details|$filename|$parent_branch|" done
Key Notes:
- Filename Inclusion: We directly append
$filenameto the output since we're looping through each file fromgit ls-files. - Parent Branch Detection: For merge commits,
$commit_id^2targets the second parent (the branch that was merged into the release branch). We filter results to match yourYYYYMMbranch naming pattern withgrep -E '^[* ] [0-9]{6}$'. - Fallback for Direct Commits: If a commit wasn't merged (it was made directly to the release branch), we label it clearly.
2. Efficiently Checking for Unmerged Changes in YYYYMM Branches
Looping through every branch one by one works, but we can optimize this by first filtering out already merged branches, then checking for uncommitted file changes in bulk. Here's a better approach:
Step-by-Step Implementation
RELEASE_BRANCH="main" # Step 1: Get all YYYYMM branches that haven't been merged into the release branch unmerged_branches=$(git for-each-ref --format='%(refname:short)' refs/heads/ | grep -E '^[0-9]{6}$' | while read branch; do if ! git merge-base --is-ancestor "$branch" "$RELEASE_BRANCH"; then echo "$branch" fi done) # Step 2: Check each file for unmerged changes in these branches for filename in $(git ls-files); do # Get the latest commit of the file in the release branch release_commit=$(git log -1 --pretty="%h" "$RELEASE_BRANCH" -- "$filename") echo "🔍 Checking file: $filename" for branch in $unmerged_branches; do # Get the latest commit of the file in the current branch (skip if file doesn't exist here) branch_commit=$(git log -1 --pretty="%h" "$branch" -- "$filename" 2>/dev/null) if [ -n "$branch_commit" ]; then # Check if the branch's commit is not already in the release branch if ! git merge-base --is-ancestor "$branch_commit" "$RELEASE_BRANCH"; then echo " ⚠️ Unmerged changes found in branch: $branch (commit: $branch_commit)" fi fi done done
Even More Efficient Bulk Check
If you want to see all unmerged commits and their changed files at once (instead of per-file), use git cherry to list commits unique to each unmerged branch:
for branch in $unmerged_branches; do echo "📋 Unmerged commits in branch: $branch" # List commits that haven't been merged into the release branch git cherry -v "$RELEASE_BRANCH" "$branch" | grep '^+' | while read line; do commit_id=$(echo "$line" | awk '{print $2}') # Show files changed in this commit changed_files=$(git show --name-only --pretty="format:" "$commit_id") echo " Commit $commit_id:" echo " $changed_files" done echo "-------------------------" done
Key Optimizations:
- Filter Merged Branches First:
git merge-base --is-ancestorquickly checks if a branch's changes are already in the release branch, so we only process relevant branches. - Bulk Commit Inspection: Using
git cherrylets you see all unmerged work in one go, which is faster than checking file-by-file for large repos.
内容的提问来源于stack exchange,提问作者Rahul Raj

