6 if not os
.environ
.has_key('GIT_DIR'):
7 os
.environ
['GIT_DIR'] = '.git'
10 print "'git-cat-file -t HEAD' failed: " + msg
11 print "Make sure that the current working directory contains a '.git' directory, or\nthat GIT_DIR is set appropriately."
15 runProgram('git-cat-file -t HEAD')
17 basicsFailed(e
.strerror
)
18 except ProgramError
, e
:
23 parseDiffRE
= re
.compile(':([0-9]+) ([0-9]+) ([0-9a-f]{40}) ([0-9a-f]{40}) ([MCRNADUT])([0-9]*)')
25 inp
= runProgram(prog
)
28 recs
= inp
.split("\0")
29 recs
.pop() # remove last entry (which is '')
33 m
= parseDiffRE
.match(rec
)
36 print "Unknown output from " + str(prog
) + "!: " + rec
+ "\n"
40 f
.srcMode
= m
.group(1)
41 f
.dstMode
= m
.group(2)
49 f
.srcName
= f
.dstName
= it
.next()
51 if f
.change
== 'C' or f
.change
== 'R':
53 f
.patch
= getPatch(f
.srcName
, f
.dstName
)
55 f
.patch
= getPatch(f
.srcName
)
63 # HEAD is src in the returned File objects. That is, srcName is the
64 # name in HEAD and dstName is the name in the cache.
66 files
= parseDiff('git-diff-cache -z -M --cached HEAD')
70 f
.text
= 'Copy from ' + f
.srcName
+ ' to ' + f
.dstName
72 f
.text
= 'Rename from ' + f
.srcName
+ ' to ' + f
.dstName
74 f
.text
= 'New file: ' + f
.srcName
76 f
.text
= 'Deleted file: ' + f
.srcName
78 f
.text
= 'Type change: ' + f
.srcName
82 if len(parseDiff(['git-diff-files', '-z', f
.dstName
])) > 0:
89 def getPatch(file, otherFile
= None):
94 return runProgram(['git-diff-cache', '-p', '-M', '--cached', 'HEAD'] + f
)
97 cacheHeadDiff
= parseDiff('git-diff-cache -z --cached HEAD')
99 # The set of files that are different in the cache compared to HEAD
101 for f
in cacheHeadDiff
:
102 cacheHeadChange
[f
.srcName
] = True
104 noncacheHeadDiff
= parseDiff('git-diff-cache -z HEAD')
105 for f
in noncacheHeadDiff
:
106 if (f
.srcSHA
== '0'*40 or f
.dstSHA
== '0'*40) and not cacheHeadChange
.has_key(f
.srcName
):
107 runProgram(['git-update-cache', '--remove', f
.srcName
])
109 def doUpdateCache(filename
):
110 runProgram(['git-update-cache', '--remove', '--add', '--replace', filename
])
113 def doCommit(filesToKeep
, fileRealNames
, msg
):
114 for file in filesToKeep
:
115 # If we have a new file in the cache which we do not want to
116 # commit we have to remove it from the cache. We will add this
117 # cache entry back in to the cache at the end of this
119 if file.change
== 'N':
120 runProgram(['git-update-cache', '--force-remove', file.srcName
])
122 runProgram(['git-update-cache', '--add', '--replace', '--cacheinfo',
123 file.srcMode
, file.srcSHA
, file.srcName
])
125 tree
= runProgram(['git-write-tree'])
127 commit
= runProgram(['git-commit-tree', tree
, '-p', 'HEAD'], msg
)
128 commit
= commit
.rstrip()
131 f
= open(os
.environ
['GIT_DIR'] + '/HEAD', 'w+')
135 raise CommitError('write to ' + os
.environ
['GIT_DIR'] + '/HEAD', e
.strerror
)
138 os
.unlink(os
.environ
['GIT_DIR'] + '/MERGE_HEAD')
142 for file in filesToKeep
:
143 # Don't add files that are going to be deleted back to the cache
144 if file.change
!= 'D':
145 runProgram(['git-update-cache', '--add', '--replace', '--cacheinfo',
146 file.dstMode
, file.dstSHA
, file.dstName
])