Is there any way of preventing files with merge conflict from getting committed in git? No one is going to commit files with conflict intentionally. But is there a way to prevent files from getting committed in git?
Does git have any settings or configurable values anywhere, where it can prevent files by looking for <<<<<<<
, =======
or >>>>>>>
symbols?
Automatic merge failed; fix conflicts and then commit the result. At least one source branch change conflicts with a target branch change. Git halts the merge and waits for you to resolve the merge conflicts. Cancel the merge by running git merge --abort , or resolve all merge conflicts then run git merge --continue .
Git commands that can help resolve merge conflicts Passing the --merge argument to the git log command will produce a log with a list of commits that conflict between the merging branches. diff helps find differences between states of a repository/files. This is useful in predicting and preventing merge conflicts.
VonC's answer already explains the different kinds of hooks where you might want to check for merge commits.
If you just want a simple solution to avoid committing conflicts, that is already included with git in the default pre-commit hook sample. Just enable the hook by renaming .git/hooks/pre-commit.sample
to .git/hooks/pre-commit
. If you then try to commit a conflict:
$ git commit -am "Fix crash in frobnicate"
src/foo.c:239: leftover conflict marker
Note:
The script uses git diff --check
internally, which also checks for various white space problems - so you might get whitespace errors as well. You can also run git diff --check
before committing to find problems. See the manpage of git diff
for details and config options.
This is valid for git V2.0; no idea when it was introduced.
You can use a pre-commit
hook, but be aware that a git commit --no-verify
would effectively ignore that.
I generally put a pre-receive
hook in order to control in a (more) central point what is being pushed.
But a pre-commmit
allows for a more timely detection (earlier in the development cycle).
Here is another example (in addition of jthill's comment), in perl.
It uses git diff-index -p -M --cached HEAD
, that is git diff-index
instead of git diff
.
I have left a few other controls done by this hook, just to showcase the kind of checks you can do in such a script.
#!/usr/bin/perl
use Modern::Perl;
use File::Basename;
my $nb_errors = 0;
my $filepath;
for my $l ( split '\n', `git diff-index -p -M --cached HEAD` ) {
if ( $l =~ /^diff --git a\/([^ ]*) .*$/ ) {
$filepath = $1;
}
given ( $l ) {
# if there is a file called *.log, stop
when ( /\.log/ ) {
say "$filepath contains console.log ($l)";
$nb_errors++;
}
# check if there is a warn, that could be unconditionnal, but just warn, don't stop
when ( /^[^(\#|\-)]+warn/ ) {
# stay silent if we're in a template, a "warn" here is fair, it's usually a message or a css class
unless ($filepath =~ /\.tt$/) {
say "$filepath contains warn ($l)";
}
}
# check if there is a ` introduced, that is a mysqlism in databases. Can be valid so don't stop, just warn
when (/^\+.*`.*/) {
say "$filepath contains a ` ($l)";
}
# check if there is a merge conflict marker and just warn (we probably could stop if there is one)
when ( m/^<<<<<</ or m/^>>>>>>/ or m/^======/ ) {
say "$filepath contains $& ($l)";
}
}
}
if ( $nb_errors ) {
say "\nAre you sure you want to commit ?";
say "You can commit with the --no-verify argument";
exit 1;
}
exit 0;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With