gnu-arch-users
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Gnu-arch-users] Conflicts/*.rej files


From: Miles Bader
Subject: Re: [Gnu-arch-users] Conflicts/*.rej files
Date: Sat, 27 Dec 2003 19:56:51 -0500
User-agent: Mutt/1.3.28i

On Sun, Dec 28, 2003 at 10:58:51AM +1100, Brian May wrote:
> What is the best of way of managing *.rej files?
> 
> So far, I have done this manually, but IMHO it is not as easy as inline
> {CVS,subversion} conflict markers.
> 
> In the past people have said to use vim's diff mode or emacs ediff
> mode, but I couldn't work out how to use the *.rej file.

If you're using an up-to-date version of emacs (I mean the original GNU Emacs,
I'm not sure about xemacs), it should enter diff-mode automatically when you
visit the .rej file.  From there, there are several useful commands you can
use, for instance, putting the cursor in a diff `hunk', and pressing `C-c C-c'
will attempt to jump to the corresponding location in the source file; typing
`C-c C-a' while in a hunk will try to actually apply the hunk (and will fail
if it can't).  Applying a hunk from diff-mode sometimes succeeds where patch
failed, though I'm not exactly sure why, as it's actually more strict about
matching the original file (it doesn't do `fuzzy' application).

So for instance a typical strategy I'll use is:

  (1) Visit the .rej file in emacs; this will automatically be in diff-mode

  (2) Make the buffer writable so I can modify the .rej file; this is just my
      personal style, you don't have to do this.  diff-mode by default makes
      the buffer read-only, but I like to delete each hunk successfully
      applied, to make bookkeeping easier for big .rej files.

  (3) Use the command `M-U' first, which converts the .rej file into `unified
      diff' format, which I find easier to read; again this is not necessary
      though, just something I like (and of course the buffer must be writable
      from step (2) to do this!).

  For each hunk:

  (3) Use C-c C-a to try to apply the hunk; if application succeeds, delete
      the hunk from the .rej file with `M-d' (.rej buffer must be writable to
      do this), and go on to next hunk, otherwise:

  (4) Use C-c C-c to find the source location -- this command will use line
      numbers as a backup strategy, so it usually gets you at least close --
      and see if there's some obvious problem where the source file has change
      from what the patch is expecting.

  (5) If there's an obvious difference, say added code in the hunk's context
      lines, _modify the hunk_ to match the source, making sure any new lines
      you add to the hunk include appropriate diff line-start characters (' ',
      '+', '-').  diff-mode will automatically make sure that the hunk line
      counts etc are kept up-to-date.  Of course this requires care, but I
      find it easier to think about the interaction of changes if I keep the
      source file unchanged and update the hunk.  If the hunk then applies,
      then delete it and contine as in step (3).

  (6) Sometimes diff generates really big hunks, which include many individual
      changes, and are difficult to think about as a whole.  For these, I
      often use the diff-mode `C-c C-s' command, to split the current hunk
      into two smaller hunks at the current line (this only works in unified
      diff format, for obvious reasons), and then deal with each smaller hunk
      individually.  Sometimes, if you're not sure where the problem in a big
      hunk is, you can use C-c C-s to do a binary search for the mismatch
      point (and use emacs' undo command to undo any split that's not useful).

The above might sound a bit complicated, but really it's not to bad once you
know the diff-mode commands.

The crucial thing I think, is that it's _much_ easier to handle non-trivial
conflicts with proper .rej files, compared to CVS conflict markers.  the
main reason I think, is that patch is more conservative, and requires a
certain amount of surrounding context to match for a patch to be applied, and
includes the failing context in the .rej files so you can see what happened.
Together with diff's habit of merging adjacent hunks into bigger hunks, this
means that potentially problematic merges are more likely to simply fail --
which is a _good_ thing...

CVS requires _no context_, and though this can be convenient for `obvious'
cases, by the time that you realize something is non-obvious, it's already
too late, CVS has already applied a bunch of possibly incorrect changes,
intermixed with non-applied changes using context markers.

-Miles
-- 
Freedom's just another word, for nothing left to lose   --Janis Joplin




reply via email to

[Prev in Thread] Current Thread [Next in Thread]