I know various ways to list git branches (just git branches
or get for-each-ref
) as well as how to check each individual branch if it has conflicts with another (lets assume origin/develop
for now):
git merge --no-commit --no-ff | awk '$1 == "CONFLICT" {print $NF}' && git merge --abort
But in lieu of doing a dry run merge on every branch (yeughh), is there a way to list all the conflicted branches/Branches with conflicted files etc?
I know various ways to list git branches (just git branches
or get for-each-ref
) as well as how to check each individual branch if it has conflicts with another (lets assume origin/develop
for now):
git merge --no-commit --no-ff | awk '$1 == "CONFLICT" {print $NF}' && git merge --abort
But in lieu of doing a dry run merge on every branch (yeughh), is there a way to list all the conflicted branches/Branches with conflicted files etc?
Share Improve this question edited Feb 6 at 18:16 Guildenstern 3,8012 gold badges28 silver badges52 bronze badges asked Feb 6 at 16:12 AncientSwordRageAncientSwordRage 7,61521 gold badges99 silver badges190 bronze badges 2 |4 Answers
Reset to default 3git-merge-tree(1) does an in-memory merge and outputs the hash of the merge, if successful. You can use that with git-for-each-ref(1) to, say, loop over branches which are not merged to whatever other ref yet.
#!/usr/bin/env bash
upstream=origin/main
for b in $(git for-each-ref \
--format="%(refname:short)" \
'refs/heads' --no-merged=$upstream)
do
git merge-tree $upstream $b >/dev/null 2>&1 \
|| printf "%s has conflicts with %s\n" "$b" "$upstream"
done
See also the “Usage Notes” section in the manual: [1]
vi message.txt
BRANCH1=refs/heads/test
BRANCH2=main
NEWTREE=$(git merge-tree --write-tree $BRANCH1 $BRANCH2) || {
echo "There were conflicts..." 1>&2
exit 1
}
NEWCOMMIT=$(git commit-tree $NEWTREE -F message.txt \
-p $BRANCH1 -p $BRANCH2)
git update-ref $BRANCH1 $NEWCOMMIT
The example script from the manual also just checks for non-zero exit
status. So that is apparently enough to check for conflicts. Although
at least one other failure mode is if the two histories are unrelated
(see --allow-unrelated-histories
).
Notes
- git version 2.48.1
But in lieu of doing a dry run merge on every branch, is there a way to list all the conflicted branches / branches with conflicted files etc?
No. The reason is that Git does not know this. It doesn't know there is a conflict (of any kind) until it attempts to enact the merge — and in order to enact a merge, the branch to be merged into must be checked out, because Git also needs a place to enact the merge.
The definition of "conflict" depends almost entirely on your merge options. Are you ignoring whitespace changes? Renormalizing for updated cross-platform eol conventions? Adopting incoming changes as improvements on existing ones?
Both tips having changes to existing files isn't necessarily, and in many workflows is often not, a conflict. You can tell Git what exactly you're considering a conflict for this merge; it has and will use factory defaults if you don't tell it differnt but the only way to tell what any particular automerge settings will regard as a conflict is to run with them.
At that point, you might as well just do a --no-commit
merge. You do not need to do a full checkout for this. git clone -ns . `mktemp -d`; cd $_; git reset -q origin/$onebranch; git merge $optionshere origin/$theother
will run a minimum-checkout merge with your desired options; if you're using lfs or other custom configs you'll probably want a --template
option on the clone; whichever, if the works you had no conflicts, if it doesn't you'll have them all (and just the ones that needed looking at) in your new temporary work tree.
Either way, the entire operation is so cheap it can be just abandoned, ordinary tempfile cleanup will get around to deleting the detritus. For instance, doing this with 20 years of linux history cost about two seconds and 8MB total. Nothing.
You could take a look at what git merge-tree
can do for you
https://git-scm.com/docs/git-merge-tree
origin/develop
, in your example), or did you want to check every possible combination of branches? – ipodtouch0218 Commented Feb 6 at 16:14git merge --abort
, but I guess it's only a typo here, we get the point.) – Romain Valeri Commented Feb 6 at 16:15