Git 是否返回特定的返回错误代码?

比如合并错误,或者重定基错误。它有唯一的错误代码吗?

96235 次浏览

I set-up a test to fail. This is what I got:

$ git merge newbranch
Auto-merging test.txt
CONFLICT (content): Merge conflict in test.txt
Automatic merge failed; fix conflicts and then commit the result.


$ echo $?
1

Git returns 0 when it merges correctly, as expected.

In short, no. You're going to see exit code 1 for errors, and 0 for success.

From a quick grepping of the source, there are some of the expected 127 and 128 for their specific purposes (command not found, errors already reported), and a few unusual codes in a few places, but for run of the mill errors, it's all exit(1).

Error 128, with no error message from git, could be a catch-all for "unexpected problem".

I was getting this on operations that needed to modify files under .git (e.g. "git checkout -- myfile" to revert a modified file) by a different user. (In my case "chmod -R og+w .git" fixed it; naturally, don't do that unless you understand the security implications for your case!)

Running git status on a non-git repo returns 128, not 1, which is helpful in quickly determining whether a git repo exists or not.

git push --delete origin a_remote_tag_name

This returns 256 if the tag doesn't exist using git version 1.8.3.1

It would be nice to have a consolidated list of specific return codes returned by each command and what they indicate. This might also help prevent changing the return code meanings (which automation scripts might rely on).

Git 2.24 (Q4 2019) does illustrate how git commands return code.

See commit 50094ca, commit c1a6f21, commit 854b5cb, commit dd2b6b6, commit 6bd26f5, commit c6ec6da, commit f2e2fa8, commit 460609c, commit 92014b6, commit 50094ca0, commit 50094ca1, commit 50094ca2 (27 Aug 2019), and commit 50094ca3 (20 Aug 2019) by commit 50094ca4.
(Merged by Junio C Hamano -- gitster -- in commit 1c6fc94, 30 Sep 2019)

t4014: stop losing return codes of git commands

Currently, there are two ways where the return codes of Git commands are lost.

The first way is when a command is in the upstream of a pipe. In a pipe, only the return code of the last command is used. Thus, all other commands will have their return codes masked.
Rewrite pipes so that there are no Git commands upstream.

The other way is when a command is in a non-assignment subshell.
The return code will be lost in favour of the surrounding command's.
Rewrite instances of this such that Git commands output to a file and surrounding commands only call subshells with non-Git commands.

So instead of writing:

git cat-file commit rebuild-1 | grep "^Side .* with .* backslash-n"

Type:

git cat-file commit rebuild-1 >actual &&
grep "^Side .* with .* backslash-n" actual