1414 INIT_FILE , CONFIG_PATH
1515from index import Index
1616from objects import Blob , Commit , Tree
17- from utils import read_file , write_to_file , cal_mode , write_object_to_file , \
18- less_str , get_all_files_in_dir , get_file_mode , filter_by_gitignore
17+ from utils import get_all_files_in_dir , read_file , write_to_file , cal_mode , \
18+ less_str , filter_by_gitignore , get_file_mode
1919
2020
2121class Repository (object ):
@@ -24,7 +24,7 @@ class Repository(object):
2424 '''
2525 def __init__ (self ):
2626 self .index = Index (INDEX_PATH )
27- self .all_files = get_all_files_in_dir ('.' , GIT_DIR )
27+ self .working_tree_files = get_all_files_in_dir ('.' , GIT_DIR )
2828 self .config = Config ()
2929 self .branch = Branch ()
3030
@@ -34,11 +34,12 @@ def stage(self, files):
3434 content = read_file (file )
3535 blob = Blob (content )
3636 if not os .path .exists (blob .path ):
37- write_object_to_file (blob .path , blob .content )
37+ write_to_file (blob .path , blob .content )
3838 stat = os .stat (os .path .join (file ))
39- self .index .add_entry (file , ctime = stat .st_ctime , mtime = stat .st_mtime , dev = stat .st_dev , ino = stat .st_ino , mode = cal_mode (stat .st_mode ), \
39+ self .index .set_entry (file , ctime = stat .st_ctime , mtime = stat .st_mtime , dev = stat .st_dev , ino = stat .st_ino , mode = cal_mode (stat .st_mode ), \
4040 uid = stat .st_uid , gid = stat .st_gid , size = stat .st_size , sha1 = blob .sha1 , flags = 0 )
4141 self .index .write_to_file ()
42+ self .index = Index (INDEX_PATH )
4243
4344 except Exception , e :
4445 print 'stage file %s error: %s' % (file , e )
@@ -83,7 +84,7 @@ def commit(self, msg):
8384
8485 commit = Commit (sha1 = None , tree_sha1 = new_tree .sha1 , parent_sha1 = self .branch .head_commit , name = committer_name , email = committer_email , \
8586 timestamp = commit_time , timezone = commit_timezone , msg = msg )
86- write_object_to_file (commit .path , commit .content )
87+ write_to_file (commit .path , commit .content )
8788 write_to_file (self .branch .head_path , commit .sha1 )
8889
8990 def delete (self , file ):
@@ -101,7 +102,7 @@ def show_log(self, num):
101102 less_str (print_str )
102103
103104 def _get_untracked_files (self ):
104- raw_list = list (set (self .all_files ).difference (set (list (self .index .entries ))))
105+ raw_list = list (set (self .working_tree_files ).difference (set (list (self .index .entries ))))
105106 return filter_by_gitignore (raw_list )
106107
107108 def _get_unstaged_files (self ):
@@ -110,7 +111,7 @@ def _get_unstaged_files(self):
110111 'deleted' : [],
111112 }
112113 for name , properties in self .index .entries .iteritems ():
113- if name not in self .all_files :
114+ if name not in self .working_tree_files :
114115 res ['deleted' ].append (name )
115116 elif get_file_mode (name ) != properties ['mode' ] or Blob (read_file (name )).sha1 != properties ['sha1' ]:
116117 res ['modified' ].append (name )
@@ -120,14 +121,14 @@ def _get_unstaged_files(self):
120121
121122 def _get_uncommitted_files (self ):
122123 if not self .branch .head_commit :
123- return {}
124+ return {'new file' : self . index . entries }
124125
125126 tree = Tree (sha1 = Commit (sha1 = self .branch .head_commit ).tree )
126127 tree_objects = tree .parse_objects ()
127128 return {
128129 'modified' : [name for name in set (self .index .entries ).intersection (set (tree_objects )) \
129130 if self .index .entries [name ]['sha1' ] != tree_objects [name ]['sha1' ] or \
130- int ( oct ( self .index .entries [name ]['mode' ])) != int ( tree_objects [name ]['mode' ]) ],
131+ self .index .entries [name ]['mode' ] != tree_objects [name ]['mode' ]],
131132 'deleted' : set (tree_objects ).difference (self .index .entries ),
132133 'new file' : set (self .index .entries ).difference (set (tree_objects )),
133134 }
@@ -137,23 +138,58 @@ def show_status(self):
137138 unstaged_files = self ._get_unstaged_files ()
138139 uncommitted_files = self ._get_uncommitted_files ()
139140 print_str = 'On branch %s\n ' % (self .branch .head_name )
140-
141- print_str += 'Changes to be committed:\n (use "git reset HEAD <file>..." to unstage)\n \n '
142- for change , files in uncommitted_files .iteritems ():
143- for file in files :
144- print_str += colored ('\t %s:\t %s\n ' % (change , file ), 'green' )
145- print_str += '\n '
146-
147- print_str += 'Changes not staged for commit:\n (use "git add <file>..." to update what will be committed)\n '
148- print_str += ' (use "git checkout -- <file>..." to discard changes in working directory)\n \n '
149- for change , files in unstaged_files .iteritems ():
150- for file in files :
151- print_str += colored ('\t %s:\t %s\n ' % (change , file ), 'red' )
152- print_str += '\n '
153-
154- print_str += 'Untracked files:\n (use "git add <file>..." to include in what will be committed)\n \n '
155- for file in untracked_files :
156- print_str += colored ('\t %s\n ' % file , 'red' )
157- print_str += '\n '
141+
142+ if uncommitted_files ['modified' ] or uncommitted_files ['deleted' ] or uncommitted_files ['new file' ]:
143+ print_str += 'Changes to be committed:\n (use "git reset HEAD <file>..." to unstage)\n \n '
144+ for change , files in uncommitted_files .iteritems ():
145+ for file in files :
146+ print_str += colored ('\t %s:\t %s\n ' % (change , file ), 'green' )
147+ print_str += '\n '
148+
149+ if unstaged_files ['modified' ] or unstaged_files ['deleted' ]:
150+ print_str += 'Changes not staged for commit:\n (use "git add <file>..." to update what will be committed)\n '
151+ print_str += ' (use "git checkout -- <file>..." to discard changes in working directory)\n \n '
152+ for change , files in unstaged_files .iteritems ():
153+ for file in files :
154+ print_str += colored ('\t %s:\t %s\n ' % (change , file ), 'red' )
155+ print_str += '\n '
156+
157+ if untracked_files :
158+ print_str += 'Untracked files:\n (use "git add <file>..." to include in what will be committed)\n \n '
159+ for file in untracked_files :
160+ print_str += colored ('\t %s\n ' % file , 'red' )
161+ print_str += '\n '
158162
159163 print print_str
164+
165+ def update_head_commit (self , commit_sha1 ):
166+ write_to_file (self .branch .head_path , commit_sha1 )
167+
168+ def rebuild_index_from_commit (self , commit_sha1 ):
169+ tree = Tree (sha1 = Commit (sha1 = commit_sha1 ).tree )
170+ tree_objects = tree .parse_objects ()
171+
172+ for name in set (self .index .entries ).difference (set (tree_objects )):
173+ self .index .entries .pop (name )
174+
175+ for name , properties in tree_objects .iteritems ():
176+ if not self .index .entries .has_key (name ) or properties ['sha1' ] != self .index .entries [name ]['sha1' ] or \
177+ properties ['mode' ] != self .index .entries [name ]['mode' ]:
178+ self .index .set_entry (name , ctime = 0.0 , mtime = 0.0 , dev = 0 , ino = 0 , mode = properties ['mode' ], \
179+ uid = 0 , gid = 0 , size = 0 , sha1 = properties ['sha1' ], flags = 0 )
180+
181+ self .index .write_to_file ()
182+ self .index = Index (INDEX_PATH )
183+
184+ def rebuild_working_tree (self ):
185+ for path , properties in self .index .entries .iteritems ():
186+ content = Blob (sha1 = properties ['sha1' ]).raw_content
187+ write_to_file (path , content , mode = properties ['mode' ])
188+
189+
190+
191+
192+
193+
194+
195+
0 commit comments