6 if not os
.environ
.has_key('GIT_DIR'):
7 os
.environ
['GIT_DIR'] = '.git'
9 if not os
.environ
.has_key('GIT_OBJECT_DIRECTORY'):
10 os
.environ
['GIT_OBJECT_DIRECTORY'] = os
.environ
['GIT_DIR'] + '/objects'
12 if not (os
.path
.exists(os
.environ
['GIT_DIR']) and
13 os
.path
.exists(os
.environ
['GIT_DIR'] + '/refs') and
14 os
.path
.exists(os
.environ
['GIT_OBJECT_DIRECTORY']) and
15 os
.path
.exists(os
.environ
['GIT_OBJECT_DIRECTORY'] + '/00')):
16 print "Git archive not found."
17 print "Make sure that the current working directory contains a '.git' directory, or\nthat GIT_DIR is set appropriately."
20 parseDiffRE
= re
.compile(':([0-9]+) ([0-9]+) ([0-9a-f]{40}) ([0-9a-f]{40}) ([MCRNADUT])([0-9]*)')
22 inp
= runProgram(prog
)
25 recs
= inp
.split("\0")
26 recs
.pop() # remove last entry (which is '')
30 m
= parseDiffRE
.match(rec
)
33 print "Unknown output from " + str(prog
) + "!: " + rec
+ "\n"
37 f
.srcMode
= m
.group(1)
38 f
.dstMode
= m
.group(2)
46 f
.srcName
= f
.dstName
= it
.next()
48 if f
.change
== 'C' or f
.change
== 'R':
50 f
.patch
= getPatch(f
.srcName
, f
.dstName
)
52 f
.patch
= getPatch(f
.srcName
)
60 # HEAD is src in the returned File objects. That is, srcName is the
61 # name in HEAD and dstName is the name in the cache.
63 files
= parseDiff('git-diff-files -z')
65 doUpdateCache(f
.srcName
)
67 files
= parseDiff('git-diff-cache -z -M --cached HEAD')
71 f
.text
= 'Copy from ' + f
.srcName
+ ' to ' + f
.dstName
73 f
.text
= 'Rename from ' + f
.srcName
+ ' to ' + f
.dstName
75 f
.text
= 'New file: ' + f
.srcName
77 f
.text
= 'Deleted file: ' + f
.srcName
79 f
.text
= 'Type change: ' + f
.srcName
85 def getPatch(file, otherFile
= None):
90 return runProgram(['git-diff-cache', '-p', '-M', '--cached', 'HEAD'] + f
)
92 def doUpdateCache(filename
):
93 runProgram(['git-update-cache', '--remove', '--add', '--replace', filename
])
95 def doCommit(filesToKeep
, fileRealNames
, msg
):
96 for file in filesToKeep
:
97 # If we have a new file in the cache which we do not want to
98 # commit we have to remove it from the cache. We will add this
99 # cache entry back in to the cache at the end of this
101 if file.change
== 'A':
102 runProgram(['git-update-cache', '--force-remove', file.srcName
])
104 runProgram(['git-update-cache', '--add', '--replace', '--cacheinfo',
105 file.srcMode
, file.srcSHA
, file.srcName
])
107 tree
= runProgram(['git-write-tree'])
109 commit
= runProgram(['git-commit-tree', tree
, '-p', 'HEAD'], msg
)
112 f
= open(os
.environ
['GIT_DIR'] + '/HEAD', 'w+')
116 raise CommitError('write to ' + os
.environ
['GIT_DIR'] + '/HEAD', e
.strerror
)
119 os
.unlink(os
.environ
['GIT_DIR'] + '/MERGE_HEAD')
123 for file in filesToKeep
:
124 # Don't add files that are going to be deleted back to the cache
125 if file.change
!= 'D':
126 runProgram(['git-update-cache', '--add', '--replace', '--cacheinfo',
127 file.dstMode
, file.dstSHA
, file.dstName
])
129 def discardFile(file):
130 runProgram(['git-read-tree', 'HEAD'])
132 if c
== 'M' or c
== 'T':
133 runProgram(['git-checkout-cache', '-f', '-q', '--', file.dstName
])
134 elif c
== 'A' or c
== 'C':
135 # The file won't be tracked by git now. We could unlink it
136 # from the working directory, but that seems a little bit
140 runProgram(['git-checkout-cache', '-f', '-q', '--', file.dstName
])
142 # Same comment applies here as to the 'A' or 'C' case.
143 runProgram(['git-checkout-cache', '-f', '-q', '--', file.srcName
])