git - pre-receive hook unable to read the committed file to push into remote master -
i tried next in pre-receive file in server pre-commit on local git repository works without issues
#!/bin/bash git rev-parse -q --verify head && sed -n -e '/^<<\+ /q1' -n -e '/^>>\+ /q1' $(git diff --name-only head^ head $(git write-tree)) || { echo "git conflict (<<<<) or (>>>>) exists in 1 of committed files."; exit 1; }
but error remote: sed: can't read /app/abc/testfile.java:no such file or directory
please help me in resolving it?
this bit of mess.
let's take part first, pre-commit hook:
git diff --name-only head^ head $(git write-tree)
the inner git write-tree
writes index tree , returns hash value. sake of illustration let's it's 01234567
.
you run git diff
3 commit-or-tree-ish arguments (all 3 arguments can resolved tree identifier, git cares here):
head^ head 01234567
this invokes undocumented bit of behavior in git diff: produces "combined diff". inputs combined diff considered several parents (all first argument) , 1 kid (the first argument), treats tree wrote, , head
commit in repository, 2 parent commits, head^
kid commit.
the git diff
documentation notes combined diff "lists files modified parents." in case, again, 2 "parents" proposed new commit's tree (from git write-tree
) , head
commit (that @ tip of current branch). both of differ head^
(the first parent of tip of current branch), git show diff. not want! (since specified --name-only
, git show file names, not actual diff.)
you take names , in files git's "conflict markers" (the <<<
, >>>
marks around conflicting regions). part not wrong (but still broken), @ point things wrong because may looking @ wrong files.
consider, instance, case commit head^
lacks file f2
, commit head
adds file f2
, , current index modifies file f3
has git conflict in it:
$ mkdir /tmp/repo; cd /tmp/repo; git init initialized empty git repository in /tmp/repo/.git/ $ echo ordinary file > f1; git add together f1 $ echo ordinary file > f3 $ git add together f1 f3; git commit -m initial [master (root-commit) f181096] initial 2 files changed, 2 insertions(+) create mode 100644 f1 create mode 100644 f3 $ echo new file f2 > f2; git add together f2 $ git commit -m 'add f2' [master c06f8d1] add together f2 1 file changed, 1 insertion(+) create mode 100644 f2 $ (echo '<<< conflict'; echo '==='; echo '>>> end conflict') > f3 $ git add together f3 # never resolved our (fake) conflict $ git diff --name-only head^ head $(git write-tree) f2
there's problem: combined diff did not @ f3
not modified in both "parents" vs "child" (of course of study these "parent"/"child" relationships nonsensical anyway). without --name-only
see combined diff output:
$ git diff head^ head $(git write-tree) diff --cc f2 index 9d57e62,9d57e62..0000000 deleted file mode 100644,100644 --- a/f2 +++ /dev/null @@@ -1,1 -1,1 +1,0 @@@ --new file f2
if want check whether proposed new commit's tree has files conflict markers, need examine proposed "blobs", rather current working tree. (this because can git add
file, modify further; or git add together -p
interactively select parts add together , parts defer adding. hence, contents of index may not match working directory.) there number of ways this; see this question , reply 1 method, , below (using git show
revision-and-path) another. code have work some cases, not all.
with out of way, see ikke has answered other issue, bare repository—the usual target git push
operations, , place run pre-receive hook—has no work tree, can't @ files in work tree. pre-receive hooks more hard write must handle many cases:
when branch (a reference of form refs/heads/name
) proposed updated, pre-receive hook gets current sha-1 , proposed new sha-1. can utilize git rev-list
find sequence of objects on (or no longer on) branch if allow update. each such object, if it's commit, examine tree attached commit, see if blobs (files) in tree pass inspection.
please note pre-receive
, update
hooks different other git "pre" hooks: in both cases, proposed new commits and/or annotated-tags in repository (although may stripped out 1 time again if hook rejects them), , should refer these proposed git objects object-id (sha-1). (it's ok walk commit tree; in fact, must in many cases.) point here right pre-commit hook guaranteed wrong pre-receive hook, , vice versa.
a rough outline of process might be:
null_sha1=0000000000000000000000000000000000000000 check_revs() { local range branch rev rtype path range=$1 branch=$2 git rev-list $range | while read rev; rtype=$(git cat-file -t $rev) case $rtype in commit) ;; *) continue;; # skip annotated tags esac git diff --name-only ${rev}^ $rev | while read path; if git show ${rev}:$path | grep forbidden-item; echo "error: branch ${branch}: ${rev}:$path contains forbidden-item" 1>&2 exit 1 fi done done } check_branch() { local old new branch old=$1 new=$2 branch=$3 if [ $old = $null_sha1 -o $new = $null_sha1 ]; # branch created or deleted, not updated # whatever appropriate here else # branch updated, if allow check_revs $old..$new $branch fi } while read oldsha newsha fullref; case "$fullref" in refs/heads/*) check_branch $oldsha $newsha ${fullref#refs/heads/};; # add together cases refs/tags/* if desired, etc *) ;; esac exit 0 # if got far must ok
(note exclusively untested. expect has bug in "file deleted" case, there nil git show
in new revision. also, it's not thought check <<<
, though. happens if there's text file illustrating how git conflicts look? can take kind of inspection based on file name, perhaps, then, files might legitimately contain like, not actually, git conflict markers. if take this, create sure allow way around if there case when should allowed.)
git bash github sed
No comments:
Post a Comment