mercurial/patch.py
changeset 12916 cfedc529e4a1
parent 12915 df1b65f8b4d4
child 13104 5dac0d04b838
equal deleted inserted replaced
12915:df1b65f8b4d4 12916:cfedc529e4a1
   972     gitlr.push(firstline)
   972     gitlr.push(firstline)
   973     gitpatches = readgitpatch(gitlr)
   973     gitpatches = readgitpatch(gitlr)
   974     fp.seek(pos)
   974     fp.seek(pos)
   975     return gitpatches
   975     return gitpatches
   976 
   976 
   977 def iterhunks(ui, fp, sourcefile=None):
   977 def iterhunks(ui, fp):
   978     """Read a patch and yield the following events:
   978     """Read a patch and yield the following events:
   979     - ("file", afile, bfile, firsthunk): select a new target file.
   979     - ("file", afile, bfile, firsthunk): select a new target file.
   980     - ("hunk", hunk): a new hunk is ready to be applied, follows a
   980     - ("hunk", hunk): a new hunk is ready to be applied, follows a
   981     "file" event.
   981     "file" event.
   982     - ("git", gitchanges): current diff is in git format, gitchanges
   982     - ("git", gitchanges): current diff is in git format, gitchanges
  1004         if current_hunk:
  1004         if current_hunk:
  1005             if x.startswith('\ '):
  1005             if x.startswith('\ '):
  1006                 current_hunk.fix_newline()
  1006                 current_hunk.fix_newline()
  1007             yield 'hunk', current_hunk
  1007             yield 'hunk', current_hunk
  1008             current_hunk = None
  1008             current_hunk = None
  1009         if ((sourcefile or state == BFILE) and ((not context and x[0] == '@') or
  1009         if (state == BFILE and ((not context and x[0] == '@') or
  1010             ((context is not False) and x.startswith('***************')))):
  1010             ((context is not False) and x.startswith('***************')))):
  1011             if context is None and x.startswith('***************'):
  1011             if context is None and x.startswith('***************'):
  1012                 context = True
  1012                 context = True
  1013             gpatch = changed.get(bfile)
  1013             gpatch = changed.get(bfile)
  1014             create = afile == '/dev/null' or gpatch and gpatch.op == 'ADD'
  1014             create = afile == '/dev/null' or gpatch and gpatch.op == 'ADD'
  1078             yield 'hunk', current_hunk
  1078             yield 'hunk', current_hunk
  1079         else:
  1079         else:
  1080             raise PatchError(_("malformed patch %s %s") % (afile,
  1080             raise PatchError(_("malformed patch %s %s") % (afile,
  1081                              current_hunk.desc))
  1081                              current_hunk.desc))
  1082 
  1082 
  1083 def applydiff(ui, fp, changed, strip=1, sourcefile=None, eolmode='strict'):
  1083 def applydiff(ui, fp, changed, strip=1, eolmode='strict'):
  1084     """Reads a patch from fp and tries to apply it.
  1084     """Reads a patch from fp and tries to apply it.
  1085 
  1085 
  1086     The dict 'changed' is filled in with all of the filenames changed
  1086     The dict 'changed' is filled in with all of the filenames changed
  1087     by the patch. Returns 0 for a clean patch, -1 if any rejects were
  1087     by the patch. Returns 0 for a clean patch, -1 if any rejects were
  1088     found and 1 if there was any fuzz.
  1088     found and 1 if there was any fuzz.
  1092     patching then normalized according to 'eolmode'.
  1092     patching then normalized according to 'eolmode'.
  1093 
  1093 
  1094     Callers probably want to call 'cmdutil.updatedir' after this to
  1094     Callers probably want to call 'cmdutil.updatedir' after this to
  1095     apply certain categories of changes not done by this function.
  1095     apply certain categories of changes not done by this function.
  1096     """
  1096     """
  1097     return _applydiff(
  1097     return _applydiff(ui, fp, patchfile, copyfile, changed, strip=strip,
  1098         ui, fp, patchfile, copyfile,
  1098                       eolmode=eolmode)
  1099         changed, strip=strip, sourcefile=sourcefile, eolmode=eolmode)
  1099 
  1100 
  1100 def _applydiff(ui, fp, patcher, copyfn, changed, strip=1, eolmode='strict'):
  1101 
       
  1102 def _applydiff(ui, fp, patcher, copyfn, changed, strip=1,
       
  1103                sourcefile=None, eolmode='strict'):
       
  1104     rejects = 0
  1101     rejects = 0
  1105     err = 0
  1102     err = 0
  1106     current_file = None
  1103     current_file = None
  1107     cwd = os.getcwd()
  1104     cwd = os.getcwd()
  1108     opener = util.opener(cwd)
  1105     opener = util.opener(cwd)
  1113         if current_file.dirty:
  1110         if current_file.dirty:
  1114             current_file.writelines(current_file.fname, current_file.lines)
  1111             current_file.writelines(current_file.fname, current_file.lines)
  1115         current_file.write_rej()
  1112         current_file.write_rej()
  1116         return len(current_file.rej)
  1113         return len(current_file.rej)
  1117 
  1114 
  1118     for state, values in iterhunks(ui, fp, sourcefile):
  1115     for state, values in iterhunks(ui, fp):
  1119         if state == 'hunk':
  1116         if state == 'hunk':
  1120             if not current_file:
  1117             if not current_file:
  1121                 continue
  1118                 continue
  1122             ret = current_file.apply(values)
  1119             ret = current_file.apply(values)
  1123             if ret >= 0:
  1120             if ret >= 0:
  1126                     err = 1
  1123                     err = 1
  1127         elif state == 'file':
  1124         elif state == 'file':
  1128             rejects += closefile()
  1125             rejects += closefile()
  1129             afile, bfile, first_hunk = values
  1126             afile, bfile, first_hunk = values
  1130             try:
  1127             try:
  1131                 if sourcefile:
  1128                 current_file, missing = selectfile(afile, bfile,
  1132                     current_file = patcher(ui, sourcefile, opener,
  1129                                                    first_hunk, strip)
  1133                                            eolmode=eolmode)
  1130                 current_file = patcher(ui, current_file, opener,
  1134                 else:
  1131                                        missing=missing, eolmode=eolmode)
  1135                     current_file, missing = selectfile(afile, bfile,
       
  1136                                                        first_hunk, strip)
       
  1137                     current_file = patcher(ui, current_file, opener,
       
  1138                                            missing=missing, eolmode=eolmode)
       
  1139             except PatchError, err:
  1132             except PatchError, err:
  1140                 ui.warn(str(err) + '\n')
  1133                 ui.warn(str(err) + '\n')
  1141                 current_file = None
  1134                 current_file = None
  1142                 rejects += 1
  1135                 rejects += 1
  1143                 continue
  1136                 continue