annotate lib/git-merge-changelog.c @ 40186:8964917f9574

autoupdate
author Karl Berry <karl@freefriends.org>
date Mon, 18 Feb 2019 08:02:49 -0800
parents d86e08b1f555
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
9690
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1 /* git-merge-changelog - git "merge" driver for GNU style ChangeLog files.
13364
f07c1f071ff0 git-merge-changelog: Enable --split-merged-entry by default.
Bruno Haible <bruno@clisp.org>
parents: 12445
diff changeset
2 Copyright (C) 2008-2010 Bruno Haible <bruno@clisp.org>
9690
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
3
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
4 This program is free software: you can redistribute it and/or modify
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
5 it under the terms of the GNU General Public License as published by
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
6 the Free Software Foundation; either version 2 of the License, or
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
7 (at your option) any later version.
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
8
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
9 This program is distributed in the hope that it will be useful,
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
12 GNU General Public License for more details.
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
13
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
14 You should have received a copy of the GNU General Public License
19190
9759915b2aca all: prefer https: URLs
Paul Eggert <eggert@cs.ucla.edu>
parents: 18477
diff changeset
15 along with this program. If not, see <https://www.gnu.org/licenses/>. */
9690
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
16
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
17 /* README:
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
18 The default merge driver of 'git' *always* produces conflicts when
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
19 pulling public modifications into a privately modified ChangeLog file.
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
20 This is because ChangeLog files are always modified at the top; the
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
21 default merge driver has no clue how to deal with this. Furthermore
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
22 the conflicts are presented with more <<<< ==== >>>> markers than
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
23 necessary; this is because the default merge driver makes pointless
11410
3c2e2d1bd42c Typo in comment.
Bruno Haible <bruno@clisp.org>
parents: 10092
diff changeset
24 efforts to look at the individual line changes inside a ChangeLog entry.
9690
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
25
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
26 This program serves as a 'git' merge driver that avoids these problems.
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
27 1. It produces no conflict when ChangeLog entries have been inserted
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
28 at the top both in the public and in the private modification. It
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
29 puts the privately added entries above the publicly added entries.
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
30 2. It respects the structure of ChangeLog files: entries are not split
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
31 into lines but kept together.
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
32 3. It also handles the case of small modifications of past ChangeLog
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
33 entries, or of removed ChangeLog entries: they are merged as one
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
34 would expect it.
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
35 4. Conflicts are presented at the top of the file, rather than where
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
36 they occurred, so that the user will see them immediately. (Unlike
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
37 for source code written in some programming language, conflict markers
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
38 that are located several hundreds lines from the top will not cause
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
39 any syntax error and therefore would be likely to remain unnoticed.)
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
40 */
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
41
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
42 /* Installation:
13551
666f1b5963c2 git-merge-changelog: add doc relating to use with bzr and hg.
Brian Gough <bjg@gnu.org>
parents: 13364
diff changeset
43
9690
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
44 $ gnulib-tool --create-testdir --dir=/tmp/testdir123 git-merge-changelog
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
45 $ cd /tmp/testdir123
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
46 $ ./configure
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
47 $ make
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
48 $ make install
13551
666f1b5963c2 git-merge-changelog: add doc relating to use with bzr and hg.
Brian Gough <bjg@gnu.org>
parents: 13364
diff changeset
49
666f1b5963c2 git-merge-changelog: add doc relating to use with bzr and hg.
Brian Gough <bjg@gnu.org>
parents: 13364
diff changeset
50 Additionally, for git users:
666f1b5963c2 git-merge-changelog: add doc relating to use with bzr and hg.
Brian Gough <bjg@gnu.org>
parents: 13364
diff changeset
51 - Add to .git/config of the checkout (or to your $HOME/.gitconfig) the
666f1b5963c2 git-merge-changelog: add doc relating to use with bzr and hg.
Brian Gough <bjg@gnu.org>
parents: 13364
diff changeset
52 lines
9690
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
53
13551
666f1b5963c2 git-merge-changelog: add doc relating to use with bzr and hg.
Brian Gough <bjg@gnu.org>
parents: 13364
diff changeset
54 [merge "merge-changelog"]
666f1b5963c2 git-merge-changelog: add doc relating to use with bzr and hg.
Brian Gough <bjg@gnu.org>
parents: 13364
diff changeset
55 name = GNU-style ChangeLog merge driver
666f1b5963c2 git-merge-changelog: add doc relating to use with bzr and hg.
Brian Gough <bjg@gnu.org>
parents: 13364
diff changeset
56 driver = /usr/local/bin/git-merge-changelog %O %A %B
666f1b5963c2 git-merge-changelog: add doc relating to use with bzr and hg.
Brian Gough <bjg@gnu.org>
parents: 13364
diff changeset
57
666f1b5963c2 git-merge-changelog: add doc relating to use with bzr and hg.
Brian Gough <bjg@gnu.org>
parents: 13364
diff changeset
58 - In every directory that contains a ChangeLog file, add a file
666f1b5963c2 git-merge-changelog: add doc relating to use with bzr and hg.
Brian Gough <bjg@gnu.org>
parents: 13364
diff changeset
59 '.gitattributes' with this line:
666f1b5963c2 git-merge-changelog: add doc relating to use with bzr and hg.
Brian Gough <bjg@gnu.org>
parents: 13364
diff changeset
60
666f1b5963c2 git-merge-changelog: add doc relating to use with bzr and hg.
Brian Gough <bjg@gnu.org>
parents: 13364
diff changeset
61 ChangeLog merge=merge-changelog
666f1b5963c2 git-merge-changelog: add doc relating to use with bzr and hg.
Brian Gough <bjg@gnu.org>
parents: 13364
diff changeset
62
666f1b5963c2 git-merge-changelog: add doc relating to use with bzr and hg.
Brian Gough <bjg@gnu.org>
parents: 13364
diff changeset
63 (See "man 5 gitattributes" for more info.)
9690
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
64
13551
666f1b5963c2 git-merge-changelog: add doc relating to use with bzr and hg.
Brian Gough <bjg@gnu.org>
parents: 13364
diff changeset
65 Additionally, for bzr users:
666f1b5963c2 git-merge-changelog: add doc relating to use with bzr and hg.
Brian Gough <bjg@gnu.org>
parents: 13364
diff changeset
66 - Install the 'extmerge' bzr plug-in listed at
666f1b5963c2 git-merge-changelog: add doc relating to use with bzr and hg.
Brian Gough <bjg@gnu.org>
parents: 13364
diff changeset
67 <http://doc.bazaar.canonical.com/plugins/en/index.html>
666f1b5963c2 git-merge-changelog: add doc relating to use with bzr and hg.
Brian Gough <bjg@gnu.org>
parents: 13364
diff changeset
68 <http://wiki.bazaar.canonical.com/BzrPlugins>
666f1b5963c2 git-merge-changelog: add doc relating to use with bzr and hg.
Brian Gough <bjg@gnu.org>
parents: 13364
diff changeset
69 - Add to your $HOME/.bazaar/bazaar.conf the line
666f1b5963c2 git-merge-changelog: add doc relating to use with bzr and hg.
Brian Gough <bjg@gnu.org>
parents: 13364
diff changeset
70
666f1b5963c2 git-merge-changelog: add doc relating to use with bzr and hg.
Brian Gough <bjg@gnu.org>
parents: 13364
diff changeset
71 external_merge = git-merge-changelog %b %T %o
666f1b5963c2 git-merge-changelog: add doc relating to use with bzr and hg.
Brian Gough <bjg@gnu.org>
parents: 13364
diff changeset
72
666f1b5963c2 git-merge-changelog: add doc relating to use with bzr and hg.
Brian Gough <bjg@gnu.org>
parents: 13364
diff changeset
73 - Then, to merge a conflict in a ChangeLog file, use
666f1b5963c2 git-merge-changelog: add doc relating to use with bzr and hg.
Brian Gough <bjg@gnu.org>
parents: 13364
diff changeset
74
666f1b5963c2 git-merge-changelog: add doc relating to use with bzr and hg.
Brian Gough <bjg@gnu.org>
parents: 13364
diff changeset
75 $ bzr extmerge ChangeLog
9690
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
76
13551
666f1b5963c2 git-merge-changelog: add doc relating to use with bzr and hg.
Brian Gough <bjg@gnu.org>
parents: 13364
diff changeset
77 Additionally, for hg users:
16708
1699b04c1c45 git-merge-changelog: add specific example on how to use with hg.
Mark Wielaard <mark@klomp.org>
parents: 16707
diff changeset
78 - Add to your $HOME/.hgrc the lines
1699b04c1c45 git-merge-changelog: add specific example on how to use with hg.
Mark Wielaard <mark@klomp.org>
parents: 16707
diff changeset
79
1699b04c1c45 git-merge-changelog: add specific example on how to use with hg.
Mark Wielaard <mark@klomp.org>
parents: 16707
diff changeset
80 [merge-patterns]
1699b04c1c45 git-merge-changelog: add specific example on how to use with hg.
Mark Wielaard <mark@klomp.org>
parents: 16707
diff changeset
81 ChangeLog = git-merge-changelog
1699b04c1c45 git-merge-changelog: add specific example on how to use with hg.
Mark Wielaard <mark@klomp.org>
parents: 16707
diff changeset
82
1699b04c1c45 git-merge-changelog: add specific example on how to use with hg.
Mark Wielaard <mark@klomp.org>
parents: 16707
diff changeset
83 [merge-tools]
1699b04c1c45 git-merge-changelog: add specific example on how to use with hg.
Mark Wielaard <mark@klomp.org>
parents: 16707
diff changeset
84 git-merge-changelog.executable = /usr/local/bin/git-merge-changelog
1699b04c1c45 git-merge-changelog: add specific example on how to use with hg.
Mark Wielaard <mark@klomp.org>
parents: 16707
diff changeset
85 git-merge-changelog.args = $base $local $other
1699b04c1c45 git-merge-changelog: add specific example on how to use with hg.
Mark Wielaard <mark@klomp.org>
parents: 16707
diff changeset
86
19192
d86e08b1f555 all: Replace many more http URLs by https URLs. Update stale URLs.
Bruno Haible <bruno@clisp.org>
parents: 19190
diff changeset
87 See <https://www.selenic.com/mercurial/hgrc.5.html> section merge-tools
13551
666f1b5963c2 git-merge-changelog: add doc relating to use with bzr and hg.
Brian Gough <bjg@gnu.org>
parents: 13364
diff changeset
88 for reference.
666f1b5963c2 git-merge-changelog: add doc relating to use with bzr and hg.
Brian Gough <bjg@gnu.org>
parents: 13364
diff changeset
89 */
9690
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
90
13551
666f1b5963c2 git-merge-changelog: add doc relating to use with bzr and hg.
Brian Gough <bjg@gnu.org>
parents: 13364
diff changeset
91 /* Use as an alternative to 'diff3':
666f1b5963c2 git-merge-changelog: add doc relating to use with bzr and hg.
Brian Gough <bjg@gnu.org>
parents: 13364
diff changeset
92 git-merge-changelog performs the same role as "diff3 -m", just with
666f1b5963c2 git-merge-changelog: add doc relating to use with bzr and hg.
Brian Gough <bjg@gnu.org>
parents: 13364
diff changeset
93 reordered arguments:
666f1b5963c2 git-merge-changelog: add doc relating to use with bzr and hg.
Brian Gough <bjg@gnu.org>
parents: 13364
diff changeset
94 $ git-merge-changelog %O %A %B
666f1b5963c2 git-merge-changelog: add doc relating to use with bzr and hg.
Brian Gough <bjg@gnu.org>
parents: 13364
diff changeset
95 is comparable to
666f1b5963c2 git-merge-changelog: add doc relating to use with bzr and hg.
Brian Gough <bjg@gnu.org>
parents: 13364
diff changeset
96 $ diff3 -m %A %O %B
9690
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
97 */
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
98
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
99 /* Calling convention:
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
100 A merge driver is called with three filename arguments:
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
101 1. %O = The common ancestor of %A and %B.
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
102 2. %A = The file's contents from the "current branch".
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
103 3. %B = The file's contents from the "other branch"; this is the contents
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
104 being merged in.
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
105
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
106 In case of a "git stash apply" or of an upstream pull (e.g. from a subsystem
9710
b2e9096015d9 Support the "git pull --rebase" situation.
Bruno Haible <bruno@clisp.org>
parents: 9693
diff changeset
107 maintainer to a central maintainer) or of a downstream pull with --rebase:
9690
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
108 2. %A = The file's newest pulled contents; modified by other committers.
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
109 3. %B = The user's newest copy of the file; modified by the user.
9710
b2e9096015d9 Support the "git pull --rebase" situation.
Bruno Haible <bruno@clisp.org>
parents: 9693
diff changeset
110 In case of a downstream pull (e.g. from a central repository to the user)
b2e9096015d9 Support the "git pull --rebase" situation.
Bruno Haible <bruno@clisp.org>
parents: 9693
diff changeset
111 or of an upstream pull with --rebase:
9690
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
112 2. %A = The user's newest copy of the file; modified by the user.
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
113 3. %B = The file's newest pulled contents; modified by other committers.
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
114
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
115 It should write its merged output into file %A. It can also echo some
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
116 remarks to stdout. It should exit with return code 0 if the merge could
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
117 be resolved cleanly, or with non-zero return code if there were conflicts.
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
118 */
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
119
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
120 /* How it works:
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
121 The structure of a ChangeLog file: It consists of ChangeLog entries. A
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
122 ChangeLog entry starts at a line following a blank line and that starts with
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
123 a non-whitespace character, or at the beginning of a file.
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
124 The merge driver works as follows: It reads the three files into memory and
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
125 dissects them into ChangeLog entries. It then finds the differences between
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
126 %O and %B. They are classified as:
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
127 - removals (some consecutive entries removed),
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
128 - changes (some consecutive entries removed, some consecutive entries
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
129 added),
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
130 - additions (some consecutive entries added).
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
131 The driver then attempts to apply the changes to %A.
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
132 To this effect, it first computes a correspondence between the entries in %O
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
133 and the entries in %A, using fuzzy string matching to still identify changed
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
134 entries.
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
135 - Removals are applied one by one. If the entry is present in %A, at any
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
136 position, it is removed. If not, the removal is marked as a conflict.
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
137 - Additions at the top of %B are applied at the top of %A.
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
138 - Additions between entry x and entry y (y may be the file end) in %B are
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
139 applied between entry x and entry y in %A (if they still exist and are
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
140 still consecutive in %A), otherwise the additions are marked as a
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
141 conflict.
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
142 - Changes are categorized into "simple changes":
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
143 entry1 ... entryn
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
144 are mapped to
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
145 added_entry ... added_entry modified_entry1 ... modified_entryn,
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
146 where the correspondence between entry_i and modified_entry_i is still
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
147 clear; and "big changes": these are all the rest. Simple changes at the
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
148 top of %B are applied by putting the added entries at the top of %A. The
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
149 changes in simple changes are applied one by one; possibly leading to
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
150 single-entry conflicts. Big changes are applied en bloc, possibly
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
151 leading to conflicts spanning multiple entries.
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
152 - Conflicts are output at the top of the file and cause an exit status of
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
153 1.
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
154 */
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
155
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
156 #include <config.h>
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
157
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
158 #include <getopt.h>
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
159 #include <limits.h>
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
160 #include <stdbool.h>
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
161 #include <stdio.h>
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
162 #include <stdlib.h>
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
163 #include <string.h>
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
164 #include <sys/types.h>
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
165 #include <unistd.h>
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
166
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
167 #include "error.h"
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
168 #include "read-file.h"
12445
a8c91b846640 Move the malloc checking from module 'list' to new module 'xlist'.
Bruno Haible <bruno@clisp.org>
parents: 12421
diff changeset
169 #include "gl_xlist.h"
9690
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
170 #include "gl_array_list.h"
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
171 #include "gl_linkedhash_list.h"
9712
a49ca512452c Speed up from O(n^2) to O(n).
Bruno Haible <bruno@clisp.org>
parents: 9711
diff changeset
172 #include "gl_rbtreehash_list.h"
9690
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
173 #include "gl_linked_list.h"
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
174 #include "xalloc.h"
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
175 #include "xmalloca.h"
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
176 #include "fstrcmp.h"
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
177 #include "minmax.h"
9710
b2e9096015d9 Support the "git pull --rebase" situation.
Bruno Haible <bruno@clisp.org>
parents: 9693
diff changeset
178 #include "c-strstr.h"
9690
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
179 #include "fwriteerror.h"
18397
dbcfb44c9695 Port modules to use getprogname explicitly
Pino Toscano <ptoscano@redhat.com>
parents: 17619
diff changeset
180 #include "getprogname.h"
9690
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
181
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
182 #define ASSERT(expr) \
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
183 do \
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
184 { \
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
185 if (!(expr)) \
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
186 abort (); \
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
187 } \
9690
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
188 while (0)
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
189
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
190 #define FSTRCMP_THRESHOLD 0.6
9711
4e8a8a9b5391 New option --split-merged-entry.
Bruno Haible <bruno@clisp.org>
parents: 9710
diff changeset
191 #define FSTRCMP_STRICTER_THRESHOLD 0.8
9690
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
192
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
193 /* Representation of a ChangeLog entry.
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
194 The string may contain NUL bytes; therefore it is represented as a plain
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
195 opaque memory region. */
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
196 struct entry
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
197 {
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
198 char *string;
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
199 size_t length;
9713
9bd638fc6986 Speed up by 25%.
Bruno Haible <bruno@clisp.org>
parents: 9712
diff changeset
200 /* Cache for the hash code. */
9bd638fc6986 Speed up by 25%.
Bruno Haible <bruno@clisp.org>
parents: 9712
diff changeset
201 bool hashcode_cached;
9bd638fc6986 Speed up by 25%.
Bruno Haible <bruno@clisp.org>
parents: 9712
diff changeset
202 size_t hashcode;
9690
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
203 };
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
204
9713
9bd638fc6986 Speed up by 25%.
Bruno Haible <bruno@clisp.org>
parents: 9712
diff changeset
205 /* Create an entry.
9bd638fc6986 Speed up by 25%.
Bruno Haible <bruno@clisp.org>
parents: 9712
diff changeset
206 The memory region passed by the caller must of indefinite extent. It is
9bd638fc6986 Speed up by 25%.
Bruno Haible <bruno@clisp.org>
parents: 9712
diff changeset
207 *not* copied here. */
9bd638fc6986 Speed up by 25%.
Bruno Haible <bruno@clisp.org>
parents: 9712
diff changeset
208 static struct entry *
9bd638fc6986 Speed up by 25%.
Bruno Haible <bruno@clisp.org>
parents: 9712
diff changeset
209 entry_create (char *string, size_t length)
9bd638fc6986 Speed up by 25%.
Bruno Haible <bruno@clisp.org>
parents: 9712
diff changeset
210 {
9bd638fc6986 Speed up by 25%.
Bruno Haible <bruno@clisp.org>
parents: 9712
diff changeset
211 struct entry *result = XMALLOC (struct entry);
9bd638fc6986 Speed up by 25%.
Bruno Haible <bruno@clisp.org>
parents: 9712
diff changeset
212 result->string = string;
9bd638fc6986 Speed up by 25%.
Bruno Haible <bruno@clisp.org>
parents: 9712
diff changeset
213 result->length = length;
9bd638fc6986 Speed up by 25%.
Bruno Haible <bruno@clisp.org>
parents: 9712
diff changeset
214 result->hashcode_cached = false;
9bd638fc6986 Speed up by 25%.
Bruno Haible <bruno@clisp.org>
parents: 9712
diff changeset
215 return result;
9bd638fc6986 Speed up by 25%.
Bruno Haible <bruno@clisp.org>
parents: 9712
diff changeset
216 }
9bd638fc6986 Speed up by 25%.
Bruno Haible <bruno@clisp.org>
parents: 9712
diff changeset
217
9690
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
218 /* Compare two entries for equality. */
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
219 static bool
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
220 entry_equals (const void *elt1, const void *elt2)
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
221 {
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
222 const struct entry *entry1 = (const struct entry *) elt1;
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
223 const struct entry *entry2 = (const struct entry *) elt2;
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
224 return entry1->length == entry2->length
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
225 && memcmp (entry1->string, entry2->string, entry1->length) == 0;
9909
adb9a924703b Remove stray semicolon.
Bruno Haible <bruno@clisp.org>
parents: 9715
diff changeset
226 }
9690
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
227
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
228 /* Return a hash code of the contents of a ChangeLog entry. */
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
229 static size_t
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
230 entry_hashcode (const void *elt)
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
231 {
9713
9bd638fc6986 Speed up by 25%.
Bruno Haible <bruno@clisp.org>
parents: 9712
diff changeset
232 struct entry *entry = (struct entry *) elt;
9bd638fc6986 Speed up by 25%.
Bruno Haible <bruno@clisp.org>
parents: 9712
diff changeset
233 if (!entry->hashcode_cached)
9bd638fc6986 Speed up by 25%.
Bruno Haible <bruno@clisp.org>
parents: 9712
diff changeset
234 {
19192
d86e08b1f555 all: Replace many more http URLs by https URLs. Update stale URLs.
Bruno Haible <bruno@clisp.org>
parents: 19190
diff changeset
235 /* See https://www.haible.de/bruno/hashfunc.html. */
9713
9bd638fc6986 Speed up by 25%.
Bruno Haible <bruno@clisp.org>
parents: 9712
diff changeset
236 const char *s;
9bd638fc6986 Speed up by 25%.
Bruno Haible <bruno@clisp.org>
parents: 9712
diff changeset
237 size_t n;
9bd638fc6986 Speed up by 25%.
Bruno Haible <bruno@clisp.org>
parents: 9712
diff changeset
238 size_t h = 0;
9690
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
239
9713
9bd638fc6986 Speed up by 25%.
Bruno Haible <bruno@clisp.org>
parents: 9712
diff changeset
240 for (s = entry->string, n = entry->length; n > 0; s++, n--)
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
241 h = (unsigned char) *s + ((h << 9) | (h >> (sizeof (size_t) * CHAR_BIT - 9)));
9690
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
242
9713
9bd638fc6986 Speed up by 25%.
Bruno Haible <bruno@clisp.org>
parents: 9712
diff changeset
243 entry->hashcode = h;
9bd638fc6986 Speed up by 25%.
Bruno Haible <bruno@clisp.org>
parents: 9712
diff changeset
244 entry->hashcode_cached = true;
9bd638fc6986 Speed up by 25%.
Bruno Haible <bruno@clisp.org>
parents: 9712
diff changeset
245 }
9bd638fc6986 Speed up by 25%.
Bruno Haible <bruno@clisp.org>
parents: 9712
diff changeset
246 return entry->hashcode;
9690
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
247 }
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
248
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
249 /* Perform a fuzzy comparison of two ChangeLog entries.
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
250 Return a similarity measure of the two entries, a value between 0 and 1.
11704
d8024cba4b63 Speed up approximate search for matching ChangeLog entries.
Bruno Haible <bruno@clisp.org>
parents: 11703
diff changeset
251 0 stands for very distinct, 1 for identical.
d8024cba4b63 Speed up approximate search for matching ChangeLog entries.
Bruno Haible <bruno@clisp.org>
parents: 11703
diff changeset
252 If the result is < LOWER_BOUND, an arbitrary other value < LOWER_BOUND can
d8024cba4b63 Speed up approximate search for matching ChangeLog entries.
Bruno Haible <bruno@clisp.org>
parents: 11703
diff changeset
253 be returned. */
9690
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
254 static double
11704
d8024cba4b63 Speed up approximate search for matching ChangeLog entries.
Bruno Haible <bruno@clisp.org>
parents: 11703
diff changeset
255 entry_fstrcmp (const struct entry *entry1, const struct entry *entry2,
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
256 double lower_bound)
9690
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
257 {
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
258 /* fstrcmp works only on NUL terminated strings. */
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
259 char *memory;
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
260 double similarity;
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
261
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
262 if (memchr (entry1->string, '\0', entry1->length) != NULL)
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
263 return 0.0;
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
264 if (memchr (entry2->string, '\0', entry2->length) != NULL)
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
265 return 0.0;
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
266 memory = (char *) xmalloca (entry1->length + 1 + entry2->length + 1);
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
267 {
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
268 char *p = memory;
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
269 memcpy (p, entry1->string, entry1->length);
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
270 p += entry1->length;
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
271 *p++ = '\0';
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
272 memcpy (p, entry2->string, entry2->length);
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
273 p += entry2->length;
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
274 *p++ = '\0';
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
275 }
11704
d8024cba4b63 Speed up approximate search for matching ChangeLog entries.
Bruno Haible <bruno@clisp.org>
parents: 11703
diff changeset
276 similarity =
d8024cba4b63 Speed up approximate search for matching ChangeLog entries.
Bruno Haible <bruno@clisp.org>
parents: 11703
diff changeset
277 fstrcmp_bounded (memory, memory + entry1->length + 1, lower_bound);
9690
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
278 freea (memory);
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
279 return similarity;
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
280 }
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
281
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
282 /* This structure represents an entire ChangeLog file, after it was read
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
283 into memory. */
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
284 struct changelog_file
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
285 {
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
286 /* The entries, as a list. */
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
287 gl_list_t /* <struct entry *> */ entries_list;
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
288 /* The entries, as a list in opposite direction. */
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
289 gl_list_t /* <struct entry *> */ entries_reversed;
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
290 /* The entries, as an array. */
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
291 size_t num_entries;
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
292 struct entry **entries;
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
293 };
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
294
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
295 /* Read a ChangeLog file into memory.
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
296 Return the contents in *RESULT. */
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
297 static void
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
298 read_changelog_file (const char *filename, struct changelog_file *result)
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
299 {
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
300 /* Read the file in text mode, otherwise it's hard to recognize empty
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
301 lines. */
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
302 size_t length;
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
303 char *contents = read_file (filename, &length);
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
304 if (contents == NULL)
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
305 {
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
306 fprintf (stderr, "could not read file '%s'\n", filename);
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
307 exit (EXIT_FAILURE);
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
308 }
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
309
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
310 result->entries_list =
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
311 gl_list_create_empty (GL_LINKEDHASH_LIST, entry_equals, entry_hashcode,
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
312 NULL, true);
9690
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
313 result->entries_reversed =
9712
a49ca512452c Speed up from O(n^2) to O(n).
Bruno Haible <bruno@clisp.org>
parents: 9711
diff changeset
314 gl_list_create_empty (GL_RBTREEHASH_LIST, entry_equals, entry_hashcode,
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
315 NULL, true);
9690
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
316 /* A ChangeLog file consists of ChangeLog entries. A ChangeLog entry starts
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
317 at a line following a blank line and that starts with a non-whitespace
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
318 character, or at the beginning of a file.
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
319 Split the file contents into entries. */
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
320 {
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
321 char *contents_end = contents + length;
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
322 char *start = contents;
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
323 while (start < contents_end)
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
324 {
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
325 /* Search the end of the current entry. */
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
326 char *ptr = start;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
327 struct entry *curr;
9690
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
328
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
329 while (ptr < contents_end)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
330 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
331 ptr = memchr (ptr, '\n', contents_end - ptr);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
332 if (ptr == NULL)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
333 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
334 ptr = contents_end;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
335 break;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
336 }
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
337 ptr++;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
338 if (contents_end - ptr >= 2
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
339 && ptr[0] == '\n'
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
340 && !(ptr[1] == '\n' || ptr[1] == '\t' || ptr[1] == ' '))
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
341 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
342 ptr++;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
343 break;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
344 }
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
345 }
9690
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
346
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
347 curr = entry_create (start, ptr - start);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
348 gl_list_add_last (result->entries_list, curr);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
349 gl_list_add_first (result->entries_reversed, curr);
9690
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
350
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
351 start = ptr;
9690
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
352 }
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
353 }
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
354
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
355 result->num_entries = gl_list_size (result->entries_list);
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
356 result->entries = XNMALLOC (result->num_entries, struct entry *);
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
357 {
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
358 size_t index = 0;
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
359 gl_list_iterator_t iter = gl_list_iterator (result->entries_list);
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
360 const void *elt;
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
361 gl_list_node_t node;
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
362 while (gl_list_iterator_next (&iter, &elt, &node))
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
363 result->entries[index++] = (struct entry *) elt;
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
364 gl_list_iterator_free (&iter);
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
365 ASSERT (index == result->num_entries);
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
366 }
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
367 }
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
368
11706
de9937c296ee Speedup git-merge-changelog for git cherry-pick.
Bruno Haible <bruno@clisp.org>
parents: 11705
diff changeset
369 /* A mapping (correspondence) between entries of FILE1 and of FILE2. */
de9937c296ee Speedup git-merge-changelog for git cherry-pick.
Bruno Haible <bruno@clisp.org>
parents: 11705
diff changeset
370 struct entries_mapping
de9937c296ee Speedup git-merge-changelog for git cherry-pick.
Bruno Haible <bruno@clisp.org>
parents: 11705
diff changeset
371 {
de9937c296ee Speedup git-merge-changelog for git cherry-pick.
Bruno Haible <bruno@clisp.org>
parents: 11705
diff changeset
372 struct changelog_file *file1;
de9937c296ee Speedup git-merge-changelog for git cherry-pick.
Bruno Haible <bruno@clisp.org>
parents: 11705
diff changeset
373 struct changelog_file *file2;
de9937c296ee Speedup git-merge-changelog for git cherry-pick.
Bruno Haible <bruno@clisp.org>
parents: 11705
diff changeset
374 /* Mapping from indices in FILE1 to indices in FILE2.
de9937c296ee Speedup git-merge-changelog for git cherry-pick.
Bruno Haible <bruno@clisp.org>
parents: 11705
diff changeset
375 A value -1 means that the entry from FILE1 is not found in FILE2.
de9937c296ee Speedup git-merge-changelog for git cherry-pick.
Bruno Haible <bruno@clisp.org>
parents: 11705
diff changeset
376 A value -2 means that it has not yet been computed. */
de9937c296ee Speedup git-merge-changelog for git cherry-pick.
Bruno Haible <bruno@clisp.org>
parents: 11705
diff changeset
377 ssize_t *index_mapping;
de9937c296ee Speedup git-merge-changelog for git cherry-pick.
Bruno Haible <bruno@clisp.org>
parents: 11705
diff changeset
378 /* Mapping from indices in FILE2 to indices in FILE1.
de9937c296ee Speedup git-merge-changelog for git cherry-pick.
Bruno Haible <bruno@clisp.org>
parents: 11705
diff changeset
379 A value -1 means that the entry from FILE2 is not found in FILE1.
de9937c296ee Speedup git-merge-changelog for git cherry-pick.
Bruno Haible <bruno@clisp.org>
parents: 11705
diff changeset
380 A value -2 means that it has not yet been computed. */
de9937c296ee Speedup git-merge-changelog for git cherry-pick.
Bruno Haible <bruno@clisp.org>
parents: 11705
diff changeset
381 ssize_t *index_mapping_reverse;
de9937c296ee Speedup git-merge-changelog for git cherry-pick.
Bruno Haible <bruno@clisp.org>
parents: 11705
diff changeset
382 };
de9937c296ee Speedup git-merge-changelog for git cherry-pick.
Bruno Haible <bruno@clisp.org>
parents: 11705
diff changeset
383
de9937c296ee Speedup git-merge-changelog for git cherry-pick.
Bruno Haible <bruno@clisp.org>
parents: 11705
diff changeset
384 /* Look up (or lazily compute) the mapping of an entry in FILE1.
de9937c296ee Speedup git-merge-changelog for git cherry-pick.
Bruno Haible <bruno@clisp.org>
parents: 11705
diff changeset
385 i is the index in FILE1.
de9937c296ee Speedup git-merge-changelog for git cherry-pick.
Bruno Haible <bruno@clisp.org>
parents: 11705
diff changeset
386 Return the index in FILE2, or -1 when the entry is not found in FILE2. */
de9937c296ee Speedup git-merge-changelog for git cherry-pick.
Bruno Haible <bruno@clisp.org>
parents: 11705
diff changeset
387 static ssize_t
de9937c296ee Speedup git-merge-changelog for git cherry-pick.
Bruno Haible <bruno@clisp.org>
parents: 11705
diff changeset
388 entries_mapping_get (struct entries_mapping *mapping, ssize_t i)
de9937c296ee Speedup git-merge-changelog for git cherry-pick.
Bruno Haible <bruno@clisp.org>
parents: 11705
diff changeset
389 {
de9937c296ee Speedup git-merge-changelog for git cherry-pick.
Bruno Haible <bruno@clisp.org>
parents: 11705
diff changeset
390 if (mapping->index_mapping[i] < -1)
de9937c296ee Speedup git-merge-changelog for git cherry-pick.
Bruno Haible <bruno@clisp.org>
parents: 11705
diff changeset
391 {
de9937c296ee Speedup git-merge-changelog for git cherry-pick.
Bruno Haible <bruno@clisp.org>
parents: 11705
diff changeset
392 struct changelog_file *file1 = mapping->file1;
de9937c296ee Speedup git-merge-changelog for git cherry-pick.
Bruno Haible <bruno@clisp.org>
parents: 11705
diff changeset
393 struct changelog_file *file2 = mapping->file2;
de9937c296ee Speedup git-merge-changelog for git cherry-pick.
Bruno Haible <bruno@clisp.org>
parents: 11705
diff changeset
394 size_t n1 = file1->num_entries;
de9937c296ee Speedup git-merge-changelog for git cherry-pick.
Bruno Haible <bruno@clisp.org>
parents: 11705
diff changeset
395 size_t n2 = file2->num_entries;
de9937c296ee Speedup git-merge-changelog for git cherry-pick.
Bruno Haible <bruno@clisp.org>
parents: 11705
diff changeset
396 struct entry *entry_i = file1->entries[i];
de9937c296ee Speedup git-merge-changelog for git cherry-pick.
Bruno Haible <bruno@clisp.org>
parents: 11705
diff changeset
397 ssize_t j;
de9937c296ee Speedup git-merge-changelog for git cherry-pick.
Bruno Haible <bruno@clisp.org>
parents: 11705
diff changeset
398
de9937c296ee Speedup git-merge-changelog for git cherry-pick.
Bruno Haible <bruno@clisp.org>
parents: 11705
diff changeset
399 /* Search whether it approximately occurs in file2. */
de9937c296ee Speedup git-merge-changelog for git cherry-pick.
Bruno Haible <bruno@clisp.org>
parents: 11705
diff changeset
400 ssize_t best_j = -1;
de9937c296ee Speedup git-merge-changelog for git cherry-pick.
Bruno Haible <bruno@clisp.org>
parents: 11705
diff changeset
401 double best_j_similarity = 0.0;
de9937c296ee Speedup git-merge-changelog for git cherry-pick.
Bruno Haible <bruno@clisp.org>
parents: 11705
diff changeset
402 for (j = n2 - 1; j >= 0; j--)
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
403 if (mapping->index_mapping_reverse[j] < 0)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
404 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
405 double similarity =
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
406 entry_fstrcmp (entry_i, file2->entries[j], best_j_similarity);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
407 if (similarity > best_j_similarity)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
408 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
409 best_j = j;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
410 best_j_similarity = similarity;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
411 }
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
412 }
11706
de9937c296ee Speedup git-merge-changelog for git cherry-pick.
Bruno Haible <bruno@clisp.org>
parents: 11705
diff changeset
413 if (best_j_similarity >= FSTRCMP_THRESHOLD)
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
414 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
415 /* Found a similar entry in file2. */
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
416 struct entry *entry_j = file2->entries[best_j];
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
417 /* Search whether it approximately occurs in file1 at index i. */
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
418 ssize_t best_i = -1;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
419 double best_i_similarity = 0.0;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
420 ssize_t ii;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
421 for (ii = n1 - 1; ii >= 0; ii--)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
422 if (mapping->index_mapping[ii] < 0)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
423 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
424 double similarity =
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
425 entry_fstrcmp (file1->entries[ii], entry_j,
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
426 best_i_similarity);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
427 if (similarity > best_i_similarity)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
428 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
429 best_i = ii;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
430 best_i_similarity = similarity;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
431 }
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
432 }
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
433 if (best_i_similarity >= FSTRCMP_THRESHOLD && best_i == i)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
434 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
435 mapping->index_mapping[i] = best_j;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
436 mapping->index_mapping_reverse[best_j] = i;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
437 }
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
438 }
11706
de9937c296ee Speedup git-merge-changelog for git cherry-pick.
Bruno Haible <bruno@clisp.org>
parents: 11705
diff changeset
439 if (mapping->index_mapping[i] < -1)
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
440 /* It does not approximately occur in FILE2.
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
441 Remember it, for next time. */
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
442 mapping->index_mapping[i] = -1;
11706
de9937c296ee Speedup git-merge-changelog for git cherry-pick.
Bruno Haible <bruno@clisp.org>
parents: 11705
diff changeset
443 }
de9937c296ee Speedup git-merge-changelog for git cherry-pick.
Bruno Haible <bruno@clisp.org>
parents: 11705
diff changeset
444 return mapping->index_mapping[i];
de9937c296ee Speedup git-merge-changelog for git cherry-pick.
Bruno Haible <bruno@clisp.org>
parents: 11705
diff changeset
445 }
de9937c296ee Speedup git-merge-changelog for git cherry-pick.
Bruno Haible <bruno@clisp.org>
parents: 11705
diff changeset
446
de9937c296ee Speedup git-merge-changelog for git cherry-pick.
Bruno Haible <bruno@clisp.org>
parents: 11705
diff changeset
447 /* Look up (or lazily compute) the mapping of an entry in FILE2.
de9937c296ee Speedup git-merge-changelog for git cherry-pick.
Bruno Haible <bruno@clisp.org>
parents: 11705
diff changeset
448 j is the index in FILE2.
de9937c296ee Speedup git-merge-changelog for git cherry-pick.
Bruno Haible <bruno@clisp.org>
parents: 11705
diff changeset
449 Return the index in FILE1, or -1 when the entry is not found in FILE1. */
de9937c296ee Speedup git-merge-changelog for git cherry-pick.
Bruno Haible <bruno@clisp.org>
parents: 11705
diff changeset
450 static ssize_t
de9937c296ee Speedup git-merge-changelog for git cherry-pick.
Bruno Haible <bruno@clisp.org>
parents: 11705
diff changeset
451 entries_mapping_reverse_get (struct entries_mapping *mapping, ssize_t j)
de9937c296ee Speedup git-merge-changelog for git cherry-pick.
Bruno Haible <bruno@clisp.org>
parents: 11705
diff changeset
452 {
de9937c296ee Speedup git-merge-changelog for git cherry-pick.
Bruno Haible <bruno@clisp.org>
parents: 11705
diff changeset
453 if (mapping->index_mapping_reverse[j] < -1)
de9937c296ee Speedup git-merge-changelog for git cherry-pick.
Bruno Haible <bruno@clisp.org>
parents: 11705
diff changeset
454 {
de9937c296ee Speedup git-merge-changelog for git cherry-pick.
Bruno Haible <bruno@clisp.org>
parents: 11705
diff changeset
455 struct changelog_file *file1 = mapping->file1;
de9937c296ee Speedup git-merge-changelog for git cherry-pick.
Bruno Haible <bruno@clisp.org>
parents: 11705
diff changeset
456 struct changelog_file *file2 = mapping->file2;
de9937c296ee Speedup git-merge-changelog for git cherry-pick.
Bruno Haible <bruno@clisp.org>
parents: 11705
diff changeset
457 size_t n1 = file1->num_entries;
de9937c296ee Speedup git-merge-changelog for git cherry-pick.
Bruno Haible <bruno@clisp.org>
parents: 11705
diff changeset
458 size_t n2 = file2->num_entries;
de9937c296ee Speedup git-merge-changelog for git cherry-pick.
Bruno Haible <bruno@clisp.org>
parents: 11705
diff changeset
459 struct entry *entry_j = file2->entries[j];
de9937c296ee Speedup git-merge-changelog for git cherry-pick.
Bruno Haible <bruno@clisp.org>
parents: 11705
diff changeset
460 ssize_t i;
de9937c296ee Speedup git-merge-changelog for git cherry-pick.
Bruno Haible <bruno@clisp.org>
parents: 11705
diff changeset
461
de9937c296ee Speedup git-merge-changelog for git cherry-pick.
Bruno Haible <bruno@clisp.org>
parents: 11705
diff changeset
462 /* Search whether it approximately occurs in file1. */
de9937c296ee Speedup git-merge-changelog for git cherry-pick.
Bruno Haible <bruno@clisp.org>
parents: 11705
diff changeset
463 ssize_t best_i = -1;
de9937c296ee Speedup git-merge-changelog for git cherry-pick.
Bruno Haible <bruno@clisp.org>
parents: 11705
diff changeset
464 double best_i_similarity = 0.0;
de9937c296ee Speedup git-merge-changelog for git cherry-pick.
Bruno Haible <bruno@clisp.org>
parents: 11705
diff changeset
465 for (i = n1 - 1; i >= 0; i--)
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
466 if (mapping->index_mapping[i] < 0)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
467 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
468 double similarity =
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
469 entry_fstrcmp (file1->entries[i], entry_j, best_i_similarity);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
470 if (similarity > best_i_similarity)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
471 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
472 best_i = i;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
473 best_i_similarity = similarity;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
474 }
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
475 }
11706
de9937c296ee Speedup git-merge-changelog for git cherry-pick.
Bruno Haible <bruno@clisp.org>
parents: 11705
diff changeset
476 if (best_i_similarity >= FSTRCMP_THRESHOLD)
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
477 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
478 /* Found a similar entry in file1. */
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
479 struct entry *entry_i = file1->entries[best_i];
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
480 /* Search whether it approximately occurs in file2 at index j. */
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
481 ssize_t best_j = -1;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
482 double best_j_similarity = 0.0;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
483 ssize_t jj;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
484 for (jj = n2 - 1; jj >= 0; jj--)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
485 if (mapping->index_mapping_reverse[jj] < 0)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
486 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
487 double similarity =
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
488 entry_fstrcmp (entry_i, file2->entries[jj],
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
489 best_j_similarity);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
490 if (similarity > best_j_similarity)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
491 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
492 best_j = jj;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
493 best_j_similarity = similarity;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
494 }
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
495 }
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
496 if (best_j_similarity >= FSTRCMP_THRESHOLD && best_j == j)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
497 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
498 mapping->index_mapping_reverse[j] = best_i;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
499 mapping->index_mapping[best_i] = j;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
500 }
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
501 }
11706
de9937c296ee Speedup git-merge-changelog for git cherry-pick.
Bruno Haible <bruno@clisp.org>
parents: 11705
diff changeset
502 if (mapping->index_mapping_reverse[j] < -1)
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
503 /* It does not approximately occur in FILE1.
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
504 Remember it, for next time. */
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
505 mapping->index_mapping_reverse[j] = -1;
11706
de9937c296ee Speedup git-merge-changelog for git cherry-pick.
Bruno Haible <bruno@clisp.org>
parents: 11705
diff changeset
506 }
de9937c296ee Speedup git-merge-changelog for git cherry-pick.
Bruno Haible <bruno@clisp.org>
parents: 11705
diff changeset
507 return mapping->index_mapping_reverse[j];
de9937c296ee Speedup git-merge-changelog for git cherry-pick.
Bruno Haible <bruno@clisp.org>
parents: 11705
diff changeset
508 }
de9937c296ee Speedup git-merge-changelog for git cherry-pick.
Bruno Haible <bruno@clisp.org>
parents: 11705
diff changeset
509
9690
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
510 /* Compute a mapping (correspondence) between entries of FILE1 and of FILE2.
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
511 The correspondence also takes into account small modifications; i.e. the
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
512 indicated relation is not equality of entries but best-match similarity
11706
de9937c296ee Speedup git-merge-changelog for git cherry-pick.
Bruno Haible <bruno@clisp.org>
parents: 11705
diff changeset
513 of entries.
de9937c296ee Speedup git-merge-changelog for git cherry-pick.
Bruno Haible <bruno@clisp.org>
parents: 11705
diff changeset
514 If FULL is true, the maximum of matching is done up-front. If it is false,
de9937c296ee Speedup git-merge-changelog for git cherry-pick.
Bruno Haible <bruno@clisp.org>
parents: 11705
diff changeset
515 it is done in a lazy way through the functions entries_mapping_get and
de9937c296ee Speedup git-merge-changelog for git cherry-pick.
Bruno Haible <bruno@clisp.org>
parents: 11705
diff changeset
516 entries_mapping_reverse_get.
de9937c296ee Speedup git-merge-changelog for git cherry-pick.
Bruno Haible <bruno@clisp.org>
parents: 11705
diff changeset
517 Return the result in *RESULT. */
9690
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
518 static void
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
519 compute_mapping (struct changelog_file *file1, struct changelog_file *file2,
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
520 bool full,
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
521 struct entries_mapping *result)
9690
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
522 {
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
523 /* Mapping from indices in file1 to indices in file2. */
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
524 ssize_t *index_mapping;
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
525 /* Mapping from indices in file2 to indices in file1. */
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
526 ssize_t *index_mapping_reverse;
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
527 size_t n1 = file1->num_entries;
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
528 size_t n2 = file2->num_entries;
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
529 ssize_t i, j;
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
530
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
531 index_mapping = XNMALLOC (n1, ssize_t);
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
532 for (i = 0; i < n1; i++)
11706
de9937c296ee Speedup git-merge-changelog for git cherry-pick.
Bruno Haible <bruno@clisp.org>
parents: 11705
diff changeset
533 index_mapping[i] = -2;
9690
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
534
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
535 index_mapping_reverse = XNMALLOC (n2, ssize_t);
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
536 for (j = 0; j < n2; j++)
11706
de9937c296ee Speedup git-merge-changelog for git cherry-pick.
Bruno Haible <bruno@clisp.org>
parents: 11705
diff changeset
537 index_mapping_reverse[j] = -2;
9690
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
538
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
539 for (i = n1 - 1; i >= 0; i--)
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
540 /* Take an entry from file1. */
11706
de9937c296ee Speedup git-merge-changelog for git cherry-pick.
Bruno Haible <bruno@clisp.org>
parents: 11705
diff changeset
541 if (index_mapping[i] < -1)
9690
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
542 {
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
543 struct entry *entry = file1->entries[i];
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
544 /* Search whether it occurs in file2. */
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
545 j = gl_list_indexof (file2->entries_reversed, entry);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
546 if (j >= 0)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
547 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
548 j = n2 - 1 - j;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
549 /* Found an exact correspondence. */
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
550 /* If index_mapping_reverse[j] >= 0, we have already seen other
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
551 copies of this entry, and there were more occurrences of it in
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
552 file1 than in file2. In this case, do nothing. */
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
553 if (index_mapping_reverse[j] < 0)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
554 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
555 index_mapping[i] = j;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
556 index_mapping_reverse[j] = i;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
557 /* Look for more occurrences of the same entry. Match them
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
558 as long as they pair up. Unpaired occurrences of the same
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
559 entry are left without mapping. */
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
560 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
561 ssize_t curr_i = i;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
562 ssize_t curr_j = j;
9690
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
563
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
564 for (;;)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
565 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
566 ssize_t next_i;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
567 ssize_t next_j;
9690
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
568
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
569 next_i =
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
570 gl_list_indexof_from (file1->entries_reversed,
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
571 n1 - curr_i, entry);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
572 if (next_i < 0)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
573 break;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
574 next_j =
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
575 gl_list_indexof_from (file2->entries_reversed,
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
576 n2 - curr_j, entry);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
577 if (next_j < 0)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
578 break;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
579 curr_i = n1 - 1 - next_i;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
580 curr_j = n2 - 1 - next_j;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
581 ASSERT (index_mapping[curr_i] < 0);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
582 ASSERT (index_mapping_reverse[curr_j] < 0);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
583 index_mapping[curr_i] = curr_j;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
584 index_mapping_reverse[curr_j] = curr_i;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
585 }
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
586 }
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
587 }
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
588 }
9690
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
589 }
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
590
11706
de9937c296ee Speedup git-merge-changelog for git cherry-pick.
Bruno Haible <bruno@clisp.org>
parents: 11705
diff changeset
591 result->file1 = file1;
de9937c296ee Speedup git-merge-changelog for git cherry-pick.
Bruno Haible <bruno@clisp.org>
parents: 11705
diff changeset
592 result->file2 = file2;
de9937c296ee Speedup git-merge-changelog for git cherry-pick.
Bruno Haible <bruno@clisp.org>
parents: 11705
diff changeset
593 result->index_mapping = index_mapping;
de9937c296ee Speedup git-merge-changelog for git cherry-pick.
Bruno Haible <bruno@clisp.org>
parents: 11705
diff changeset
594 result->index_mapping_reverse = index_mapping_reverse;
9690
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
595
11706
de9937c296ee Speedup git-merge-changelog for git cherry-pick.
Bruno Haible <bruno@clisp.org>
parents: 11705
diff changeset
596 if (full)
de9937c296ee Speedup git-merge-changelog for git cherry-pick.
Bruno Haible <bruno@clisp.org>
parents: 11705
diff changeset
597 for (i = n1 - 1; i >= 0; i--)
de9937c296ee Speedup git-merge-changelog for git cherry-pick.
Bruno Haible <bruno@clisp.org>
parents: 11705
diff changeset
598 entries_mapping_get (result, i);
9690
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
599 }
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
600
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
601 /* An "edit" is a textual modification performed by the user, that needs to
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
602 be applied to the other file. */
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
603 enum edit_type
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
604 {
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
605 /* Some consecutive entries were added. */
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
606 ADDITION,
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
607 /* Some consecutive entries were removed; some other consecutive entries
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
608 were added at the same position. (Not necessarily the same number of
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
609 entries.) */
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
610 CHANGE,
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
611 /* Some consecutive entries were removed. */
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
612 REMOVAL
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
613 };
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
614
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
615 /* This structure represents an edit. */
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
616 struct edit
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
617 {
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
618 enum edit_type type;
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
619 /* Range of indices into the entries of FILE1. */
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
620 ssize_t i1, i2; /* first, last index; only used for CHANGE, REMOVAL */
9690
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
621 /* Range of indices into the entries of FILE2. */
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
622 ssize_t j1, j2; /* first, last index; only used for ADDITION, CHANGE */
9690
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
623 };
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
624
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
625 /* This structure represents the differences from one file, FILE1, to another
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
626 file, FILE2. */
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
627 struct differences
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
628 {
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
629 /* An array mapping FILE1 indices to FILE2 indices (or -1 when the entry
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
630 from FILE1 is not found in FILE2). */
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
631 ssize_t *index_mapping;
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
632 /* An array mapping FILE2 indices to FILE1 indices (or -1 when the entry
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
633 from FILE2 is not found in FILE1). */
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
634 ssize_t *index_mapping_reverse;
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
635 /* The edits that transform FILE1 into FILE2. */
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
636 size_t num_edits;
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
637 struct edit **edits;
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
638 };
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
639
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
640 /* Import the difference detection algorithm from GNU diff. */
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
641 #define ELEMENT struct entry *
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
642 #define EQUAL entry_equals
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
643 #define OFFSET ssize_t
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
644 #define EXTRA_CONTEXT_FIELDS \
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
645 ssize_t *index_mapping; \
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
646 ssize_t *index_mapping_reverse;
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
647 #define NOTE_DELETE(ctxt, xoff) \
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
648 ctxt->index_mapping[xoff] = -1
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
649 #define NOTE_INSERT(ctxt, yoff) \
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
650 ctxt->index_mapping_reverse[yoff] = -1
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
651 #include "diffseq.h"
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
652
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
653 /* Compute the differences between the entries of FILE1 and the entries of
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
654 FILE2. */
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
655 static void
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
656 compute_differences (struct changelog_file *file1, struct changelog_file *file2,
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
657 struct differences *result)
9690
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
658 {
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
659 /* Unlike compute_mapping, which mostly ignores the order of the entries and
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
660 therefore works well when some entries are permuted, here we use the order.
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
661 I think this is needed in order to distinguish changes from
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
662 additions+removals; I don't know how to say what is a "change" if the
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
663 files are considered as unordered sets of entries. */
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
664 struct context ctxt;
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
665 size_t n1 = file1->num_entries;
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
666 size_t n2 = file2->num_entries;
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
667 ssize_t i;
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
668 ssize_t j;
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
669 gl_list_t /* <struct edit *> */ edits;
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
670
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
671 ctxt.xvec = file1->entries;
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
672 ctxt.yvec = file2->entries;
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
673 ctxt.index_mapping = XNMALLOC (n1, ssize_t);
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
674 for (i = 0; i < n1; i++)
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
675 ctxt.index_mapping[i] = 0;
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
676 ctxt.index_mapping_reverse = XNMALLOC (n2, ssize_t);
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
677 for (j = 0; j < n2; j++)
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
678 ctxt.index_mapping_reverse[j] = 0;
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
679 ctxt.fdiag = XNMALLOC (2 * (n1 + n2 + 3), ssize_t) + n2 + 1;
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
680 ctxt.bdiag = ctxt.fdiag + n1 + n2 + 3;
18477
8d64577babf5 diffseq: restore TOO_EXPENSIVE heuristic
Paul Eggert <eggert@cs.ucla.edu>
parents: 18397
diff changeset
681 ctxt.too_expensive = n1 + n2;
9690
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
682
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
683 /* Store in ctxt.index_mapping and ctxt.index_mapping_reverse a -1 for
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
684 each removed or added entry. */
18477
8d64577babf5 diffseq: restore TOO_EXPENSIVE heuristic
Paul Eggert <eggert@cs.ucla.edu>
parents: 18397
diff changeset
685 compareseq (0, n1, 0, n2, 0, &ctxt);
9690
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
686
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
687 /* Complete the index_mapping and index_mapping_reverse arrays. */
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
688 i = 0;
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
689 j = 0;
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
690 while (i < n1 || j < n2)
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
691 {
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
692 while (i < n1 && ctxt.index_mapping[i] < 0)
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
693 i++;
9690
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
694 while (j < n2 && ctxt.index_mapping_reverse[j] < 0)
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
695 j++;
9690
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
696 ASSERT ((i < n1) == (j < n2));
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
697 if (i == n1 && j == n2)
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
698 break;
9690
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
699 ctxt.index_mapping[i] = j;
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
700 ctxt.index_mapping_reverse[j] = i;
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
701 i++;
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
702 j++;
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
703 }
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
704
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
705 /* Create the edits. */
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
706 edits = gl_list_create_empty (GL_ARRAY_LIST, NULL, NULL, NULL, true);
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
707 i = 0;
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
708 j = 0;
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
709 while (i < n1 || j < n2)
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
710 {
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
711 if (i == n1)
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
712 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
713 struct edit *e;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
714 ASSERT (j < n2);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
715 e = XMALLOC (struct edit);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
716 e->type = ADDITION;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
717 e->j1 = j;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
718 e->j2 = n2 - 1;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
719 gl_list_add_last (edits, e);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
720 break;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
721 }
9690
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
722 if (j == n2)
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
723 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
724 struct edit *e;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
725 ASSERT (i < n1);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
726 e = XMALLOC (struct edit);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
727 e->type = REMOVAL;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
728 e->i1 = i;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
729 e->i2 = n1 - 1;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
730 gl_list_add_last (edits, e);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
731 break;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
732 }
9690
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
733 if (ctxt.index_mapping[i] >= 0)
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
734 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
735 if (ctxt.index_mapping_reverse[j] >= 0)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
736 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
737 ASSERT (ctxt.index_mapping[i] == j);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
738 ASSERT (ctxt.index_mapping_reverse[j] == i);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
739 i++;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
740 j++;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
741 }
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
742 else
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
743 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
744 struct edit *e;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
745 ASSERT (ctxt.index_mapping_reverse[j] < 0);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
746 e = XMALLOC (struct edit);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
747 e->type = ADDITION;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
748 e->j1 = j;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
749 do
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
750 j++;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
751 while (j < n2 && ctxt.index_mapping_reverse[j] < 0);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
752 e->j2 = j - 1;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
753 gl_list_add_last (edits, e);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
754 }
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
755 }
9690
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
756 else
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
757 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
758 if (ctxt.index_mapping_reverse[j] >= 0)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
759 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
760 struct edit *e;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
761 ASSERT (ctxt.index_mapping[i] < 0);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
762 e = XMALLOC (struct edit);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
763 e->type = REMOVAL;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
764 e->i1 = i;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
765 do
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
766 i++;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
767 while (i < n1 && ctxt.index_mapping[i] < 0);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
768 e->i2 = i - 1;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
769 gl_list_add_last (edits, e);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
770 }
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
771 else
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
772 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
773 struct edit *e;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
774 ASSERT (ctxt.index_mapping[i] < 0);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
775 ASSERT (ctxt.index_mapping_reverse[j] < 0);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
776 e = XMALLOC (struct edit);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
777 e->type = CHANGE;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
778 e->i1 = i;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
779 do
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
780 i++;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
781 while (i < n1 && ctxt.index_mapping[i] < 0);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
782 e->i2 = i - 1;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
783 e->j1 = j;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
784 do
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
785 j++;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
786 while (j < n2 && ctxt.index_mapping_reverse[j] < 0);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
787 e->j2 = j - 1;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
788 gl_list_add_last (edits, e);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
789 }
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
790 }
9690
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
791 }
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
792
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
793 result->index_mapping = ctxt.index_mapping;
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
794 result->index_mapping_reverse = ctxt.index_mapping_reverse;
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
795 result->num_edits = gl_list_size (edits);
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
796 result->edits = XNMALLOC (result->num_edits, struct edit *);
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
797 {
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
798 size_t index = 0;
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
799 gl_list_iterator_t iter = gl_list_iterator (edits);
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
800 const void *elt;
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
801 gl_list_node_t node;
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
802 while (gl_list_iterator_next (&iter, &elt, &node))
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
803 result->edits[index++] = (struct edit *) elt;
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
804 gl_list_iterator_free (&iter);
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
805 ASSERT (index == result->num_edits);
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
806 }
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
807 }
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
808
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
809 /* An empty entry. */
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
810 static struct entry empty_entry = { NULL, 0 };
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
811
9711
4e8a8a9b5391 New option --split-merged-entry.
Bruno Haible <bruno@clisp.org>
parents: 9710
diff changeset
812 /* Return the end a paragraph.
4e8a8a9b5391 New option --split-merged-entry.
Bruno Haible <bruno@clisp.org>
parents: 9710
diff changeset
813 ENTRY is an entry.
4e8a8a9b5391 New option --split-merged-entry.
Bruno Haible <bruno@clisp.org>
parents: 9710
diff changeset
814 OFFSET is an offset into the entry, OFFSET <= ENTRY->length.
4e8a8a9b5391 New option --split-merged-entry.
Bruno Haible <bruno@clisp.org>
parents: 9710
diff changeset
815 Return the offset of the end of paragraph, as an offset <= ENTRY->length;
4e8a8a9b5391 New option --split-merged-entry.
Bruno Haible <bruno@clisp.org>
parents: 9710
diff changeset
816 it is the start of a blank line or the end of the entry. */
4e8a8a9b5391 New option --split-merged-entry.
Bruno Haible <bruno@clisp.org>
parents: 9710
diff changeset
817 static size_t
4e8a8a9b5391 New option --split-merged-entry.
Bruno Haible <bruno@clisp.org>
parents: 9710
diff changeset
818 find_paragraph_end (const struct entry *entry, size_t offset)
4e8a8a9b5391 New option --split-merged-entry.
Bruno Haible <bruno@clisp.org>
parents: 9710
diff changeset
819 {
4e8a8a9b5391 New option --split-merged-entry.
Bruno Haible <bruno@clisp.org>
parents: 9710
diff changeset
820 const char *string = entry->string;
4e8a8a9b5391 New option --split-merged-entry.
Bruno Haible <bruno@clisp.org>
parents: 9710
diff changeset
821 size_t length = entry->length;
4e8a8a9b5391 New option --split-merged-entry.
Bruno Haible <bruno@clisp.org>
parents: 9710
diff changeset
822
4e8a8a9b5391 New option --split-merged-entry.
Bruno Haible <bruno@clisp.org>
parents: 9710
diff changeset
823 for (;;)
4e8a8a9b5391 New option --split-merged-entry.
Bruno Haible <bruno@clisp.org>
parents: 9710
diff changeset
824 {
4e8a8a9b5391 New option --split-merged-entry.
Bruno Haible <bruno@clisp.org>
parents: 9710
diff changeset
825 const char *nl = memchr (string + offset, '\n', length - offset);
4e8a8a9b5391 New option --split-merged-entry.
Bruno Haible <bruno@clisp.org>
parents: 9710
diff changeset
826 if (nl == NULL)
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
827 return length;
9711
4e8a8a9b5391 New option --split-merged-entry.
Bruno Haible <bruno@clisp.org>
parents: 9710
diff changeset
828 offset = (nl - string) + 1;
4e8a8a9b5391 New option --split-merged-entry.
Bruno Haible <bruno@clisp.org>
parents: 9710
diff changeset
829 if (offset < length && string[offset] == '\n')
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
830 return offset;
9711
4e8a8a9b5391 New option --split-merged-entry.
Bruno Haible <bruno@clisp.org>
parents: 9710
diff changeset
831 }
4e8a8a9b5391 New option --split-merged-entry.
Bruno Haible <bruno@clisp.org>
parents: 9710
diff changeset
832 }
4e8a8a9b5391 New option --split-merged-entry.
Bruno Haible <bruno@clisp.org>
parents: 9710
diff changeset
833
4e8a8a9b5391 New option --split-merged-entry.
Bruno Haible <bruno@clisp.org>
parents: 9710
diff changeset
834 /* Split a merged entry.
4e8a8a9b5391 New option --split-merged-entry.
Bruno Haible <bruno@clisp.org>
parents: 9710
diff changeset
835 Given an old entry of the form
4e8a8a9b5391 New option --split-merged-entry.
Bruno Haible <bruno@clisp.org>
parents: 9710
diff changeset
836 TITLE
4e8a8a9b5391 New option --split-merged-entry.
Bruno Haible <bruno@clisp.org>
parents: 9710
diff changeset
837 BODY
4e8a8a9b5391 New option --split-merged-entry.
Bruno Haible <bruno@clisp.org>
parents: 9710
diff changeset
838 and a new entry of the form
4e8a8a9b5391 New option --split-merged-entry.
Bruno Haible <bruno@clisp.org>
parents: 9710
diff changeset
839 TITLE
4e8a8a9b5391 New option --split-merged-entry.
Bruno Haible <bruno@clisp.org>
parents: 9710
diff changeset
840 BODY1
4e8a8a9b5391 New option --split-merged-entry.
Bruno Haible <bruno@clisp.org>
parents: 9710
diff changeset
841 BODY'
4e8a8a9b5391 New option --split-merged-entry.
Bruno Haible <bruno@clisp.org>
parents: 9710
diff changeset
842 where the two titles are the same and BODY and BODY' are very similar,
4e8a8a9b5391 New option --split-merged-entry.
Bruno Haible <bruno@clisp.org>
parents: 9710
diff changeset
843 this computes two new entries
4e8a8a9b5391 New option --split-merged-entry.
Bruno Haible <bruno@clisp.org>
parents: 9710
diff changeset
844 TITLE
4e8a8a9b5391 New option --split-merged-entry.
Bruno Haible <bruno@clisp.org>
parents: 9710
diff changeset
845 BODY1
4e8a8a9b5391 New option --split-merged-entry.
Bruno Haible <bruno@clisp.org>
parents: 9710
diff changeset
846 and
4e8a8a9b5391 New option --split-merged-entry.
Bruno Haible <bruno@clisp.org>
parents: 9710
diff changeset
847 TITLE
4e8a8a9b5391 New option --split-merged-entry.
Bruno Haible <bruno@clisp.org>
parents: 9710
diff changeset
848 BODY'
4e8a8a9b5391 New option --split-merged-entry.
Bruno Haible <bruno@clisp.org>
parents: 9710
diff changeset
849 and returns true.
4e8a8a9b5391 New option --split-merged-entry.
Bruno Haible <bruno@clisp.org>
parents: 9710
diff changeset
850 If the entries don't have this form, it returns false. */
4e8a8a9b5391 New option --split-merged-entry.
Bruno Haible <bruno@clisp.org>
parents: 9710
diff changeset
851 static bool
4e8a8a9b5391 New option --split-merged-entry.
Bruno Haible <bruno@clisp.org>
parents: 9710
diff changeset
852 try_split_merged_entry (const struct entry *old_entry,
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
853 const struct entry *new_entry,
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
854 struct entry *new_split[2])
9711
4e8a8a9b5391 New option --split-merged-entry.
Bruno Haible <bruno@clisp.org>
parents: 9710
diff changeset
855 {
4e8a8a9b5391 New option --split-merged-entry.
Bruno Haible <bruno@clisp.org>
parents: 9710
diff changeset
856 size_t old_title_len = find_paragraph_end (old_entry, 0);
4e8a8a9b5391 New option --split-merged-entry.
Bruno Haible <bruno@clisp.org>
parents: 9710
diff changeset
857 size_t new_title_len = find_paragraph_end (new_entry, 0);
4e8a8a9b5391 New option --split-merged-entry.
Bruno Haible <bruno@clisp.org>
parents: 9710
diff changeset
858 struct entry old_body;
4e8a8a9b5391 New option --split-merged-entry.
Bruno Haible <bruno@clisp.org>
parents: 9710
diff changeset
859 struct entry new_body;
4e8a8a9b5391 New option --split-merged-entry.
Bruno Haible <bruno@clisp.org>
parents: 9710
diff changeset
860 size_t best_split_offset;
4e8a8a9b5391 New option --split-merged-entry.
Bruno Haible <bruno@clisp.org>
parents: 9710
diff changeset
861 double best_similarity;
4e8a8a9b5391 New option --split-merged-entry.
Bruno Haible <bruno@clisp.org>
parents: 9710
diff changeset
862 size_t split_offset;
4e8a8a9b5391 New option --split-merged-entry.
Bruno Haible <bruno@clisp.org>
parents: 9710
diff changeset
863
4e8a8a9b5391 New option --split-merged-entry.
Bruno Haible <bruno@clisp.org>
parents: 9710
diff changeset
864 /* Same title? */
4e8a8a9b5391 New option --split-merged-entry.
Bruno Haible <bruno@clisp.org>
parents: 9710
diff changeset
865 if (!(old_title_len == new_title_len
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
866 && memcmp (old_entry->string, new_entry->string, old_title_len) == 0))
9711
4e8a8a9b5391 New option --split-merged-entry.
Bruno Haible <bruno@clisp.org>
parents: 9710
diff changeset
867 return false;
4e8a8a9b5391 New option --split-merged-entry.
Bruno Haible <bruno@clisp.org>
parents: 9710
diff changeset
868
4e8a8a9b5391 New option --split-merged-entry.
Bruno Haible <bruno@clisp.org>
parents: 9710
diff changeset
869 old_body.string = old_entry->string + old_title_len;
4e8a8a9b5391 New option --split-merged-entry.
Bruno Haible <bruno@clisp.org>
parents: 9710
diff changeset
870 old_body.length = old_entry->length - old_title_len;
4e8a8a9b5391 New option --split-merged-entry.
Bruno Haible <bruno@clisp.org>
parents: 9710
diff changeset
871
4e8a8a9b5391 New option --split-merged-entry.
Bruno Haible <bruno@clisp.org>
parents: 9710
diff changeset
872 /* Determine where to split the new entry.
4e8a8a9b5391 New option --split-merged-entry.
Bruno Haible <bruno@clisp.org>
parents: 9710
diff changeset
873 This is done by maximizing the similarity between BODY and BODY'. */
4e8a8a9b5391 New option --split-merged-entry.
Bruno Haible <bruno@clisp.org>
parents: 9710
diff changeset
874 best_split_offset = split_offset = new_title_len;
4e8a8a9b5391 New option --split-merged-entry.
Bruno Haible <bruno@clisp.org>
parents: 9710
diff changeset
875 best_similarity = 0.0;
4e8a8a9b5391 New option --split-merged-entry.
Bruno Haible <bruno@clisp.org>
parents: 9710
diff changeset
876 for (;;)
4e8a8a9b5391 New option --split-merged-entry.
Bruno Haible <bruno@clisp.org>
parents: 9710
diff changeset
877 {
4e8a8a9b5391 New option --split-merged-entry.
Bruno Haible <bruno@clisp.org>
parents: 9710
diff changeset
878 double similarity;
4e8a8a9b5391 New option --split-merged-entry.
Bruno Haible <bruno@clisp.org>
parents: 9710
diff changeset
879
4e8a8a9b5391 New option --split-merged-entry.
Bruno Haible <bruno@clisp.org>
parents: 9710
diff changeset
880 new_body.string = new_entry->string + split_offset;
4e8a8a9b5391 New option --split-merged-entry.
Bruno Haible <bruno@clisp.org>
parents: 9710
diff changeset
881 new_body.length = new_entry->length - split_offset;
11704
d8024cba4b63 Speed up approximate search for matching ChangeLog entries.
Bruno Haible <bruno@clisp.org>
parents: 11703
diff changeset
882 similarity =
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
883 entry_fstrcmp (&old_body, &new_body, best_similarity);
9711
4e8a8a9b5391 New option --split-merged-entry.
Bruno Haible <bruno@clisp.org>
parents: 9710
diff changeset
884 if (similarity > best_similarity)
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
885 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
886 best_split_offset = split_offset;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
887 best_similarity = similarity;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
888 }
9711
4e8a8a9b5391 New option --split-merged-entry.
Bruno Haible <bruno@clisp.org>
parents: 9710
diff changeset
889 if (best_similarity == 1.0)
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
890 /* It cannot get better. */
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
891 break;
9711
4e8a8a9b5391 New option --split-merged-entry.
Bruno Haible <bruno@clisp.org>
parents: 9710
diff changeset
892
4e8a8a9b5391 New option --split-merged-entry.
Bruno Haible <bruno@clisp.org>
parents: 9710
diff changeset
893 if (split_offset < new_entry->length)
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
894 split_offset = find_paragraph_end (new_entry, split_offset + 1);
9711
4e8a8a9b5391 New option --split-merged-entry.
Bruno Haible <bruno@clisp.org>
parents: 9710
diff changeset
895 else
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
896 break;
9711
4e8a8a9b5391 New option --split-merged-entry.
Bruno Haible <bruno@clisp.org>
parents: 9710
diff changeset
897 }
4e8a8a9b5391 New option --split-merged-entry.
Bruno Haible <bruno@clisp.org>
parents: 9710
diff changeset
898
4e8a8a9b5391 New option --split-merged-entry.
Bruno Haible <bruno@clisp.org>
parents: 9710
diff changeset
899 /* BODY' should not be empty. */
4e8a8a9b5391 New option --split-merged-entry.
Bruno Haible <bruno@clisp.org>
parents: 9710
diff changeset
900 if (best_split_offset == new_entry->length)
4e8a8a9b5391 New option --split-merged-entry.
Bruno Haible <bruno@clisp.org>
parents: 9710
diff changeset
901 return false;
4e8a8a9b5391 New option --split-merged-entry.
Bruno Haible <bruno@clisp.org>
parents: 9710
diff changeset
902 ASSERT (new_entry->string[best_split_offset] == '\n');
4e8a8a9b5391 New option --split-merged-entry.
Bruno Haible <bruno@clisp.org>
parents: 9710
diff changeset
903
4e8a8a9b5391 New option --split-merged-entry.
Bruno Haible <bruno@clisp.org>
parents: 9710
diff changeset
904 /* A certain similarity between BODY and BODY' is required. */
4e8a8a9b5391 New option --split-merged-entry.
Bruno Haible <bruno@clisp.org>
parents: 9710
diff changeset
905 if (best_similarity < FSTRCMP_STRICTER_THRESHOLD)
4e8a8a9b5391 New option --split-merged-entry.
Bruno Haible <bruno@clisp.org>
parents: 9710
diff changeset
906 return false;
4e8a8a9b5391 New option --split-merged-entry.
Bruno Haible <bruno@clisp.org>
parents: 9710
diff changeset
907
9713
9bd638fc6986 Speed up by 25%.
Bruno Haible <bruno@clisp.org>
parents: 9712
diff changeset
908 new_split[0] = entry_create (new_entry->string, best_split_offset + 1);
9711
4e8a8a9b5391 New option --split-merged-entry.
Bruno Haible <bruno@clisp.org>
parents: 9710
diff changeset
909
4e8a8a9b5391 New option --split-merged-entry.
Bruno Haible <bruno@clisp.org>
parents: 9710
diff changeset
910 {
4e8a8a9b5391 New option --split-merged-entry.
Bruno Haible <bruno@clisp.org>
parents: 9710
diff changeset
911 size_t len1 = new_title_len;
4e8a8a9b5391 New option --split-merged-entry.
Bruno Haible <bruno@clisp.org>
parents: 9710
diff changeset
912 size_t len2 = new_entry->length - best_split_offset;
4e8a8a9b5391 New option --split-merged-entry.
Bruno Haible <bruno@clisp.org>
parents: 9710
diff changeset
913 char *combined = XNMALLOC (len1 + len2, char);
4e8a8a9b5391 New option --split-merged-entry.
Bruno Haible <bruno@clisp.org>
parents: 9710
diff changeset
914 memcpy (combined, new_entry->string, len1);
4e8a8a9b5391 New option --split-merged-entry.
Bruno Haible <bruno@clisp.org>
parents: 9710
diff changeset
915 memcpy (combined + len1, new_entry->string + best_split_offset, len2);
9713
9bd638fc6986 Speed up by 25%.
Bruno Haible <bruno@clisp.org>
parents: 9712
diff changeset
916 new_split[1] = entry_create (combined, len1 + len2);
9711
4e8a8a9b5391 New option --split-merged-entry.
Bruno Haible <bruno@clisp.org>
parents: 9710
diff changeset
917 }
4e8a8a9b5391 New option --split-merged-entry.
Bruno Haible <bruno@clisp.org>
parents: 9710
diff changeset
918
4e8a8a9b5391 New option --split-merged-entry.
Bruno Haible <bruno@clisp.org>
parents: 9710
diff changeset
919 return true;
4e8a8a9b5391 New option --split-merged-entry.
Bruno Haible <bruno@clisp.org>
parents: 9710
diff changeset
920 }
4e8a8a9b5391 New option --split-merged-entry.
Bruno Haible <bruno@clisp.org>
parents: 9710
diff changeset
921
9690
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
922 /* Write the contents of an entry to the output stream FP. */
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
923 static void
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
924 entry_write (FILE *fp, struct entry *entry)
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
925 {
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
926 if (entry->length > 0)
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
927 fwrite (entry->string, 1, entry->length, fp);
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
928 }
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
929
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
930 /* This structure represents a conflict.
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
931 A conflict can occur for various reasons. */
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
932 struct conflict
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
933 {
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
934 /* Parts from the ancestor file. */
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
935 size_t num_old_entries;
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
936 struct entry **old_entries;
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
937 /* Parts of the modified file. */
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
938 size_t num_modified_entries;
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
939 struct entry **modified_entries;
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
940 };
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
941
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
942 /* Write a conflict to the output stream FP, including markers. */
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
943 static void
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
944 conflict_write (FILE *fp, struct conflict *c)
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
945 {
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
946 size_t i;
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
947
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
948 /* Use the same syntax as git's default merge driver.
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
949 Don't indent the contents of the entries (with things like ">" or "-"),
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
950 otherwise the user needs more textual editing to resolve the conflict. */
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
951 fputs ("<<<<<<<\n", fp);
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
952 for (i = 0; i < c->num_old_entries; i++)
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
953 entry_write (fp, c->old_entries[i]);
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
954 fputs ("=======\n", fp);
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
955 for (i = 0; i < c->num_modified_entries; i++)
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
956 entry_write (fp, c->modified_entries[i]);
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
957 fputs (">>>>>>>\n", fp);
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
958 }
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
959
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
960 /* Long options. */
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
961 static const struct option long_options[] =
10092
ae7bf97ee30c Remove trailing spaces.
Bruno Haible <bruno@clisp.org>
parents: 9909
diff changeset
962 {
9690
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
963 { "help", no_argument, NULL, 'h' },
9711
4e8a8a9b5391 New option --split-merged-entry.
Bruno Haible <bruno@clisp.org>
parents: 9710
diff changeset
964 { "split-merged-entry", no_argument, NULL, CHAR_MAX + 1 },
9690
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
965 { "version", no_argument, NULL, 'V' },
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
966 { NULL, 0, NULL, 0 }
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
967 };
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
968
16358
a712776b11ce maint: spelling fixes
Paul Eggert <eggert@cs.ucla.edu>
parents: 16234
diff changeset
969 /* Print a usage message and exit. */
9690
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
970 static void
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
971 usage (int status)
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
972 {
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
973 if (status != EXIT_SUCCESS)
16234
f9b906545e2f Use ', not `, for quoting output.
Paul Eggert <eggert@cs.ucla.edu>
parents: 13551
diff changeset
974 fprintf (stderr, "Try '%s --help' for more information.\n",
18397
dbcfb44c9695 Port modules to use getprogname explicitly
Pino Toscano <ptoscano@redhat.com>
parents: 17619
diff changeset
975 getprogname ());
9690
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
976 else
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
977 {
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
978 printf ("Usage: %s [OPTION] O-FILE-NAME A-FILE-NAME B-FILE-NAME\n",
18397
dbcfb44c9695 Port modules to use getprogname explicitly
Pino Toscano <ptoscano@redhat.com>
parents: 17619
diff changeset
979 getprogname ());
9690
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
980 printf ("\n");
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
981 printf ("Merges independent modifications of a ChangeLog style file.\n");
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
982 printf ("O-FILE-NAME names the original file, the ancestor of the two others.\n");
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
983 printf ("A-FILE-NAME names the publicly modified file.\n");
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
984 printf ("B-FILE-NAME names the user-modified file.\n");
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
985 printf ("Writes the merged file into A-FILE-NAME.\n");
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
986 printf ("\n");
13364
f07c1f071ff0 git-merge-changelog: Enable --split-merged-entry by default.
Bruno Haible <bruno@clisp.org>
parents: 12445
diff changeset
987 #if 0 /* --split-merged-entry is now on by default. */
9711
4e8a8a9b5391 New option --split-merged-entry.
Bruno Haible <bruno@clisp.org>
parents: 9710
diff changeset
988 printf ("Operation modifiers:\n");
4e8a8a9b5391 New option --split-merged-entry.
Bruno Haible <bruno@clisp.org>
parents: 9710
diff changeset
989 printf ("\
4e8a8a9b5391 New option --split-merged-entry.
Bruno Haible <bruno@clisp.org>
parents: 9710
diff changeset
990 --split-merged-entry Possibly split a merged entry between paragraphs.\n\
4e8a8a9b5391 New option --split-merged-entry.
Bruno Haible <bruno@clisp.org>
parents: 9710
diff changeset
991 Use this if you have the habit to merge unrelated\n\
4e8a8a9b5391 New option --split-merged-entry.
Bruno Haible <bruno@clisp.org>
parents: 9710
diff changeset
992 entries into a single one, separated only by a\n\
4e8a8a9b5391 New option --split-merged-entry.
Bruno Haible <bruno@clisp.org>
parents: 9710
diff changeset
993 newline, just because they happened on the same\n\
4e8a8a9b5391 New option --split-merged-entry.
Bruno Haible <bruno@clisp.org>
parents: 9710
diff changeset
994 date.\n");
4e8a8a9b5391 New option --split-merged-entry.
Bruno Haible <bruno@clisp.org>
parents: 9710
diff changeset
995 printf ("\n");
13364
f07c1f071ff0 git-merge-changelog: Enable --split-merged-entry by default.
Bruno Haible <bruno@clisp.org>
parents: 12445
diff changeset
996 #endif
9690
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
997 printf ("Informative output:\n");
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
998 printf (" -h, --help display this help and exit\n");
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
999 printf (" -V, --version output version information and exit\n");
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1000 printf ("\n");
16707
47613935f655 git-merge-changelog: Report bugs to bug-gnulib@gnu.org.
Mark Wielaard <mark@klomp.org>
parents: 16358
diff changeset
1001 fputs ("Report bugs to <bug-gnulib@gnu.org>.\n",
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1002 stdout);
9690
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1003 }
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1004
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1005 exit (status);
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1006 }
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1007
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1008 int
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1009 main (int argc, char *argv[])
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1010 {
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1011 int optchar;
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1012 bool do_help;
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1013 bool do_version;
9711
4e8a8a9b5391 New option --split-merged-entry.
Bruno Haible <bruno@clisp.org>
parents: 9710
diff changeset
1014 bool split_merged_entry;
9690
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1015
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1016 /* Set default values for variables. */
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1017 do_help = false;
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1018 do_version = false;
13364
f07c1f071ff0 git-merge-changelog: Enable --split-merged-entry by default.
Bruno Haible <bruno@clisp.org>
parents: 12445
diff changeset
1019 split_merged_entry = true;
9690
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1020
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1021 /* Parse command line options. */
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1022 while ((optchar = getopt_long (argc, argv, "hV", long_options, NULL)) != EOF)
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1023 switch (optchar)
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1024 {
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1025 case '\0': /* Long option. */
9690
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1026 break;
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1027 case 'h':
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1028 do_help = true;
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1029 break;
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1030 case 'V':
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1031 do_version = true;
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1032 break;
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1033 case CHAR_MAX + 1: /* --split-merged-entry */
9711
4e8a8a9b5391 New option --split-merged-entry.
Bruno Haible <bruno@clisp.org>
parents: 9710
diff changeset
1034 break;
4e8a8a9b5391 New option --split-merged-entry.
Bruno Haible <bruno@clisp.org>
parents: 9710
diff changeset
1035 default:
9690
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1036 usage (EXIT_FAILURE);
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1037 }
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1038
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1039 if (do_version)
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1040 {
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1041 /* Version information is requested. */
18397
dbcfb44c9695 Port modules to use getprogname explicitly
Pino Toscano <ptoscano@redhat.com>
parents: 17619
diff changeset
1042 printf ("%s\n", getprogname ());
9690
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1043 printf ("Copyright (C) %s Free Software Foundation, Inc.\n\
19190
9759915b2aca all: prefer https: URLs
Paul Eggert <eggert@cs.ucla.edu>
parents: 18477
diff changeset
1044 License GPLv2+: GNU GPL version 2 or later <https://gnu.org/licenses/gpl.html>\n\
9690
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1045 This is free software: you are free to change and redistribute it.\n\
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1046 There is NO WARRANTY, to the extent permitted by law.\n\
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1047 ",
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1048 "2008");
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1049 printf ("Written by %s.\n", "Bruno Haible");
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1050 exit (EXIT_SUCCESS);
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1051 }
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1052
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1053 if (do_help)
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1054 {
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1055 /* Help is requested. */
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1056 usage (EXIT_SUCCESS);
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1057 }
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1058
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1059 /* Test argument count. */
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1060 if (optind + 3 != argc)
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1061 error (EXIT_FAILURE, 0, "expected three arguments");
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1062
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1063 {
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1064 const char *ancestor_file_name; /* O-FILE-NAME */
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1065 const char *destination_file_name; /* A-FILE-NAME */
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1066 bool downstream;
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1067 const char *other_file_name; /* B-FILE-NAME */
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1068 const char *mainstream_file_name;
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1069 const char *modified_file_name;
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1070 struct changelog_file ancestor_file;
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1071 struct changelog_file mainstream_file;
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1072 struct changelog_file modified_file;
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1073 /* Mapping from indices in ancestor_file to indices in mainstream_file. */
11706
de9937c296ee Speedup git-merge-changelog for git cherry-pick.
Bruno Haible <bruno@clisp.org>
parents: 11705
diff changeset
1074 struct entries_mapping mapping;
9690
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1075 struct differences diffs;
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1076 gl_list_node_t *result_entries_pointers; /* array of pointers into result_entries */
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1077 gl_list_t /* <struct entry *> */ result_entries;
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1078 gl_list_t /* <struct conflict *> */ result_conflicts;
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1079
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1080 ancestor_file_name = argv[optind];
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1081 destination_file_name = argv[optind + 1];
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1082 other_file_name = argv[optind + 2];
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1083
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1084 /* Heuristic to determine whether it's a pull in downstream direction
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1085 (e.g. pull from a centralized server) or a pull in upstream direction
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1086 (e.g. "git stash apply").
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1087
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1088 For ChangeLog this distinction is important. The difference between
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1089 an "upstream" and a "downstream" repository is that more people are
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1090 looking at the "upstream" repository. They want to be informed about
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1091 changes and expect them to be shown at the top of the ChangeLog.
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1092 When a user pulls downstream, on the other hand, he has two options:
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1093 a) He gets the change entries from the central repository also at the
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1094 top of his ChangeLog, and his own changes come after them.
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1095 b) He gets the change entries from the central repository after those
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1096 he has collected for his branch. His own change entries stay at
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1097 the top of the ChangeLog file.
9690
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1098 In the case a) he has to reorder the ChangeLog before he can commit.
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1099 No one does that. So most people want b).
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1100 In other words, the order of entries in a ChangeLog should represent
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1101 the order in which they have flown (or will flow) into the *central*
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1102 repository.
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1103
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1104 But in git this is fundamentally indistinguishable, because when Linus
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1105 pulls patches from akpm and akpm pulls patches from Linus, it's not
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1106 clear which of the two is more "upstream". Also, when you have many
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1107 branches in a repository and pull from one to another, "git" has no way
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1108 to know which branch is more "upstream" than the other. The git-tag(1)
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1109 manual page also says:
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1110 "One important aspect of git is it is distributed, and being
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1111 distributed largely means there is no inherent "upstream" or
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1112 "downstream" in the system."
9690
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1113 Therefore anyone who attempts to produce a ChangeLog from the merge
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1114 history will fail.
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1115
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1116 Here we allow the user to specify the pull direction through an
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1117 environment variable (GIT_UPSTREAM or GIT_DOWNSTREAM). If these two
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1118 environment variables are not set, we assume a "simple single user"
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1119 usage pattern: He manages local changes through stashes and uses
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1120 "git pull" only to pull downstream.
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1121
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1122 How to distinguish these situation? There are several hints:
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1123 - During a "git stash apply", GIT_REFLOG_ACTION is not set. During
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1124 a "git pull", it is set to 'pull '. During a "git pull --rebase",
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1125 it is set to 'pull --rebase'. During a "git cherry-pick", it is
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1126 set to 'cherry-pick'.
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1127 - During a "git stash apply", there is an environment variable of
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1128 the form GITHEAD_<40_hex_digits>='Stashed changes'. */
9690
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1129 {
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1130 const char *var;
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1131
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1132 var = getenv ("GIT_DOWNSTREAM");
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1133 if (var != NULL && var[0] != '\0')
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1134 downstream = true;
9690
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1135 else
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1136 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1137 var = getenv ("GIT_UPSTREAM");
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1138 if (var != NULL && var[0] != '\0')
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1139 downstream = false;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1140 else
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1141 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1142 var = getenv ("GIT_REFLOG_ACTION");
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1143 #if 0 /* Debugging code */
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1144 printf ("GIT_REFLOG_ACTION=|%s|\n", var);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1145 #endif
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1146 if (var != NULL
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1147 && ((strncmp (var, "pull", 4) == 0
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1148 && c_strstr (var, " --rebase") == NULL)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1149 || strncmp (var, "merge origin", 12) == 0))
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1150 downstream = true;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1151 else
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1152 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1153 /* "git stash apply", "git rebase", "git cherry-pick" and
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1154 similar. */
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1155 downstream = false;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1156 }
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1157 }
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1158 }
9690
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1159 }
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1160
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1161 #if 0 /* Debugging code */
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1162 {
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1163 char buf[1000];
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1164 printf ("First line of %%A:\n");
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1165 sprintf (buf, "head -1 %s", destination_file_name); system (buf);
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1166 printf ("First line of %%B:\n");
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1167 sprintf (buf, "head -1 %s", other_file_name); system (buf);
9710
b2e9096015d9 Support the "git pull --rebase" situation.
Bruno Haible <bruno@clisp.org>
parents: 9693
diff changeset
1168 printf ("Guessing calling convention: %s\n",
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1169 downstream
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1170 ? "%A = modified by user, %B = upstream"
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1171 : "%A = upstream, %B = modified by user");
9690
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1172 }
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1173 #endif
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1174
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1175 if (downstream)
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1176 {
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1177 mainstream_file_name = other_file_name;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1178 modified_file_name = destination_file_name;
9690
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1179 }
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1180 else
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1181 {
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1182 mainstream_file_name = destination_file_name;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1183 modified_file_name = other_file_name;
9690
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1184 }
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1185
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1186 /* Read the three files into memory. */
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1187 read_changelog_file (ancestor_file_name, &ancestor_file);
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1188 read_changelog_file (mainstream_file_name, &mainstream_file);
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1189 read_changelog_file (modified_file_name, &modified_file);
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1190
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1191 /* Compute correspondence between the entries of ancestor_file and of
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1192 mainstream_file. */
11706
de9937c296ee Speedup git-merge-changelog for git cherry-pick.
Bruno Haible <bruno@clisp.org>
parents: 11705
diff changeset
1193 compute_mapping (&ancestor_file, &mainstream_file, false, &mapping);
de9937c296ee Speedup git-merge-changelog for git cherry-pick.
Bruno Haible <bruno@clisp.org>
parents: 11705
diff changeset
1194 (void) entries_mapping_reverse_get; /* avoid gcc "defined but not" warning */
9690
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1195
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1196 /* Compute differences between the entries of ancestor_file and of
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1197 modified_file. */
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1198 compute_differences (&ancestor_file, &modified_file, &diffs);
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1199
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1200 /* Compute the result. */
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1201 result_entries_pointers =
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1202 XNMALLOC (mainstream_file.num_entries, gl_list_node_t);
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1203 result_entries =
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1204 gl_list_create_empty (GL_LINKED_LIST, entry_equals, entry_hashcode,
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1205 NULL, true);
9690
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1206 {
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1207 size_t k;
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1208 for (k = 0; k < mainstream_file.num_entries; k++)
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1209 result_entries_pointers[k] =
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1210 gl_list_add_last (result_entries, mainstream_file.entries[k]);
9690
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1211 }
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1212 result_conflicts =
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1213 gl_list_create_empty (GL_ARRAY_LIST, NULL, NULL, NULL, true);
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1214 {
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1215 size_t e;
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1216 for (e = 0; e < diffs.num_edits; e++)
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1217 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1218 struct edit *edit = diffs.edits[e];
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1219 switch (edit->type)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1220 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1221 case ADDITION:
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1222 if (edit->j1 == 0)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1223 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1224 /* An addition to the top of modified_file.
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1225 Apply it to the top of mainstream_file. */
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1226 ssize_t j;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1227 for (j = edit->j2; j >= edit->j1; j--)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1228 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1229 struct entry *added_entry = modified_file.entries[j];
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1230 gl_list_add_first (result_entries, added_entry);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1231 }
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1232 }
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1233 else
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1234 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1235 ssize_t i_before;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1236 ssize_t i_after;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1237 ssize_t k_before;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1238 ssize_t k_after;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1239 i_before = diffs.index_mapping_reverse[edit->j1 - 1];
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1240 ASSERT (i_before >= 0);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1241 i_after = (edit->j2 + 1 == modified_file.num_entries
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1242 ? ancestor_file.num_entries
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1243 : diffs.index_mapping_reverse[edit->j2 + 1]);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1244 ASSERT (i_after >= 0);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1245 ASSERT (i_after == i_before + 1);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1246 /* An addition between ancestor_file.entries[i_before] and
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1247 ancestor_file.entries[i_after]. See whether these two
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1248 entries still exist in mainstream_file and are still
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1249 consecutive. */
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1250 k_before = entries_mapping_get (&mapping, i_before);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1251 k_after = (i_after == ancestor_file.num_entries
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1252 ? mainstream_file.num_entries
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1253 : entries_mapping_get (&mapping, i_after));
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1254 if (k_before >= 0 && k_after >= 0 && k_after == k_before + 1)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1255 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1256 /* Yes, the entry before and after are still neighbours
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1257 in mainstream_file. Apply the addition between
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1258 them. */
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1259 if (k_after == mainstream_file.num_entries)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1260 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1261 size_t j;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1262 for (j = edit->j1; j <= edit->j2; j++)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1263 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1264 struct entry *added_entry = modified_file.entries[j];
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1265 gl_list_add_last (result_entries, added_entry);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1266 }
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1267 }
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1268 else
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1269 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1270 gl_list_node_t node_k_after = result_entries_pointers[k_after];
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1271 size_t j;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1272 for (j = edit->j1; j <= edit->j2; j++)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1273 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1274 struct entry *added_entry = modified_file.entries[j];
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1275 gl_list_add_before (result_entries, node_k_after, added_entry);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1276 }
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1277 }
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1278 }
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1279 else
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1280 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1281 /* It's not clear where the additions should be applied.
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1282 Let the user decide. */
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1283 struct conflict *c = XMALLOC (struct conflict);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1284 size_t j;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1285 c->num_old_entries = 0;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1286 c->old_entries = NULL;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1287 c->num_modified_entries = edit->j2 - edit->j1 + 1;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1288 c->modified_entries =
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1289 XNMALLOC (c->num_modified_entries, struct entry *);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1290 for (j = edit->j1; j <= edit->j2; j++)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1291 c->modified_entries[j - edit->j1] = modified_file.entries[j];
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1292 gl_list_add_last (result_conflicts, c);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1293 }
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1294 }
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1295 break;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1296 case REMOVAL:
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1297 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1298 /* Apply the removals one by one. */
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1299 size_t i;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1300 for (i = edit->i1; i <= edit->i2; i++)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1301 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1302 struct entry *removed_entry = ancestor_file.entries[i];
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1303 ssize_t k = entries_mapping_get (&mapping, i);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1304 if (k >= 0
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1305 && entry_equals (removed_entry,
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1306 mainstream_file.entries[k]))
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1307 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1308 /* The entry to be removed still exists in
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1309 mainstream_file. Remove it. */
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1310 gl_list_node_set_value (result_entries,
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1311 result_entries_pointers[k],
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1312 &empty_entry);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1313 }
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1314 else
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1315 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1316 /* The entry to be removed was already removed or was
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1317 modified. This is a conflict. */
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1318 struct conflict *c = XMALLOC (struct conflict);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1319 c->num_old_entries = 1;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1320 c->old_entries =
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1321 XNMALLOC (c->num_old_entries, struct entry *);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1322 c->old_entries[0] = removed_entry;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1323 c->num_modified_entries = 0;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1324 c->modified_entries = NULL;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1325 gl_list_add_last (result_conflicts, c);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1326 }
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1327 }
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1328 }
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1329 break;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1330 case CHANGE:
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1331 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1332 bool done = false;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1333 /* When the user usually merges entries from the same day,
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1334 and this edit is at the top of the file: */
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1335 if (split_merged_entry && edit->j1 == 0)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1336 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1337 /* Test whether the change is "simple merged", i.e. whether
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1338 it consists of additions, followed by an augmentation of
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1339 the first changed entry, followed by small changes of the
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1340 remaining entries:
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1341 entry_1
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1342 entry_2
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1343 ...
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1344 entry_n
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1345 are mapped to
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1346 added_entry
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1347 ...
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1348 added_entry
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1349 augmented_entry_1
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1350 modified_entry_2
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1351 ...
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1352 modified_entry_n. */
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1353 if (edit->i2 - edit->i1 <= edit->j2 - edit->j1)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1354 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1355 struct entry *split[2];
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1356 bool simple_merged =
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1357 try_split_merged_entry (ancestor_file.entries[edit->i1],
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1358 modified_file.entries[edit->i1 + edit->j2 - edit->i2],
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1359 split);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1360 if (simple_merged)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1361 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1362 size_t i;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1363 for (i = edit->i1 + 1; i <= edit->i2; i++)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1364 if (entry_fstrcmp (ancestor_file.entries[i],
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1365 modified_file.entries[i + edit->j2 - edit->i2],
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1366 FSTRCMP_THRESHOLD)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1367 < FSTRCMP_THRESHOLD)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1368 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1369 simple_merged = false;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1370 break;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1371 }
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1372 }
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1373 if (simple_merged)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1374 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1375 /* Apply the additions at the top of modified_file.
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1376 Apply each of the single-entry changes
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1377 separately. */
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1378 size_t num_changed = edit->i2 - edit->i1 + 1; /* > 0 */
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1379 size_t num_added = (edit->j2 - edit->j1 + 1) - num_changed;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1380 ssize_t j;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1381 /* First part of the split modified_file.entries[edit->j2 - edit->i2 + edit->i1]: */
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1382 gl_list_add_first (result_entries, split[0]);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1383 /* The additions. */
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1384 for (j = edit->j1 + num_added - 1; j >= edit->j1; j--)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1385 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1386 struct entry *added_entry = modified_file.entries[j];
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1387 gl_list_add_first (result_entries, added_entry);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1388 }
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1389 /* Now the single-entry changes. */
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1390 for (j = edit->j1 + num_added; j <= edit->j2; j++)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1391 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1392 struct entry *changed_entry =
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1393 (j == edit->j1 + num_added
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1394 ? split[1]
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1395 : modified_file.entries[j]);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1396 size_t i = j + edit->i2 - edit->j2;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1397 ssize_t k = entries_mapping_get (&mapping, i);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1398 if (k >= 0
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1399 && entry_equals (ancestor_file.entries[i],
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1400 mainstream_file.entries[k]))
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1401 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1402 gl_list_node_set_value (result_entries,
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1403 result_entries_pointers[k],
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1404 changed_entry);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1405 }
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1406 else if (!entry_equals (ancestor_file.entries[i],
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1407 changed_entry))
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1408 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1409 struct conflict *c = XMALLOC (struct conflict);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1410 c->num_old_entries = 1;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1411 c->old_entries =
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1412 XNMALLOC (c->num_old_entries, struct entry *);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1413 c->old_entries[0] = ancestor_file.entries[i];
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1414 c->num_modified_entries = 1;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1415 c->modified_entries =
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1416 XNMALLOC (c->num_modified_entries, struct entry *);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1417 c->modified_entries[0] = changed_entry;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1418 gl_list_add_last (result_conflicts, c);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1419 }
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1420 }
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1421 done = true;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1422 }
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1423 }
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1424 }
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1425 if (!done)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1426 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1427 bool simple;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1428 /* Test whether the change is "simple", i.e. whether it
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1429 consists of small changes to the old ChangeLog entries
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1430 and additions before them:
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1431 entry_1
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1432 ...
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1433 entry_n
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1434 are mapped to
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1435 added_entry
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1436 ...
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1437 added_entry
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1438 modified_entry_1
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1439 ...
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1440 modified_entry_n. */
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1441 if (edit->i2 - edit->i1 <= edit->j2 - edit->j1)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1442 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1443 size_t i;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1444 simple = true;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1445 for (i = edit->i1; i <= edit->i2; i++)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1446 if (entry_fstrcmp (ancestor_file.entries[i],
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1447 modified_file.entries[i + edit->j2 - edit->i2],
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1448 FSTRCMP_THRESHOLD)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1449 < FSTRCMP_THRESHOLD)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1450 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1451 simple = false;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1452 break;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1453 }
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1454 }
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1455 else
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1456 simple = false;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1457 if (simple)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1458 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1459 /* Apply the additions and each of the single-entry
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1460 changes separately. */
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1461 size_t num_changed = edit->i2 - edit->i1 + 1; /* > 0 */
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1462 size_t num_added = (edit->j2 - edit->j1 + 1) - num_changed;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1463 if (edit->j1 == 0)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1464 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1465 /* A simple change at the top of modified_file.
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1466 Apply it to the top of mainstream_file. */
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1467 ssize_t j;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1468 for (j = edit->j1 + num_added - 1; j >= edit->j1; j--)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1469 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1470 struct entry *added_entry = modified_file.entries[j];
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1471 gl_list_add_first (result_entries, added_entry);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1472 }
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1473 for (j = edit->j1 + num_added; j <= edit->j2; j++)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1474 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1475 struct entry *changed_entry = modified_file.entries[j];
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1476 size_t i = j + edit->i2 - edit->j2;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1477 ssize_t k = entries_mapping_get (&mapping, i);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1478 if (k >= 0
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1479 && entry_equals (ancestor_file.entries[i],
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1480 mainstream_file.entries[k]))
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1481 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1482 gl_list_node_set_value (result_entries,
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1483 result_entries_pointers[k],
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1484 changed_entry);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1485 }
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1486 else
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1487 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1488 struct conflict *c;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1489 ASSERT (!entry_equals (ancestor_file.entries[i],
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1490 changed_entry));
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1491 c = XMALLOC (struct conflict);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1492 c->num_old_entries = 1;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1493 c->old_entries =
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1494 XNMALLOC (c->num_old_entries, struct entry *);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1495 c->old_entries[0] = ancestor_file.entries[i];
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1496 c->num_modified_entries = 1;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1497 c->modified_entries =
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1498 XNMALLOC (c->num_modified_entries, struct entry *);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1499 c->modified_entries[0] = changed_entry;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1500 gl_list_add_last (result_conflicts, c);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1501 }
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1502 }
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1503 done = true;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1504 }
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1505 else
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1506 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1507 ssize_t i_before;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1508 ssize_t k_before;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1509 bool linear;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1510 i_before = diffs.index_mapping_reverse[edit->j1 - 1];
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1511 ASSERT (i_before >= 0);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1512 /* A simple change after ancestor_file.entries[i_before].
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1513 See whether this entry and the following num_changed
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1514 entries still exist in mainstream_file and are still
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1515 consecutive. */
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1516 k_before = entries_mapping_get (&mapping, i_before);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1517 linear = (k_before >= 0);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1518 if (linear)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1519 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1520 size_t i;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1521 for (i = i_before + 1; i <= i_before + num_changed; i++)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1522 if (entries_mapping_get (&mapping, i) != k_before + (i - i_before))
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1523 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1524 linear = false;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1525 break;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1526 }
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1527 }
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1528 if (linear)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1529 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1530 gl_list_node_t node_for_insert =
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1531 result_entries_pointers[k_before + 1];
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1532 ssize_t j;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1533 for (j = edit->j1 + num_added - 1; j >= edit->j1; j--)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1534 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1535 struct entry *added_entry = modified_file.entries[j];
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1536 gl_list_add_before (result_entries, node_for_insert, added_entry);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1537 }
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1538 for (j = edit->j1 + num_added; j <= edit->j2; j++)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1539 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1540 struct entry *changed_entry = modified_file.entries[j];
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1541 size_t i = j + edit->i2 - edit->j2;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1542 ssize_t k = entries_mapping_get (&mapping, i);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1543 ASSERT (k >= 0);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1544 if (entry_equals (ancestor_file.entries[i],
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1545 mainstream_file.entries[k]))
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1546 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1547 gl_list_node_set_value (result_entries,
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1548 result_entries_pointers[k],
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1549 changed_entry);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1550 }
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1551 else
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1552 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1553 struct conflict *c;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1554 ASSERT (!entry_equals (ancestor_file.entries[i],
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1555 changed_entry));
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1556 c = XMALLOC (struct conflict);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1557 c->num_old_entries = 1;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1558 c->old_entries =
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1559 XNMALLOC (c->num_old_entries, struct entry *);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1560 c->old_entries[0] = ancestor_file.entries[i];
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1561 c->num_modified_entries = 1;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1562 c->modified_entries =
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1563 XNMALLOC (c->num_modified_entries, struct entry *);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1564 c->modified_entries[0] = changed_entry;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1565 gl_list_add_last (result_conflicts, c);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1566 }
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1567 }
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1568 done = true;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1569 }
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1570 }
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1571 }
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1572 else
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1573 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1574 /* A big change.
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1575 See whether the num_changed entries still exist
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1576 unchanged in mainstream_file and are still
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1577 consecutive. */
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1578 ssize_t i_first;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1579 ssize_t k_first;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1580 bool linear_unchanged;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1581 i_first = edit->i1;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1582 k_first = entries_mapping_get (&mapping, i_first);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1583 linear_unchanged =
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1584 (k_first >= 0
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1585 && entry_equals (ancestor_file.entries[i_first],
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1586 mainstream_file.entries[k_first]));
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1587 if (linear_unchanged)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1588 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1589 size_t i;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1590 for (i = i_first + 1; i <= edit->i2; i++)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1591 if (!(entries_mapping_get (&mapping, i) == k_first + (i - i_first)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1592 && entry_equals (ancestor_file.entries[i],
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1593 mainstream_file.entries[entries_mapping_get (&mapping, i)])))
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1594 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1595 linear_unchanged = false;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1596 break;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1597 }
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1598 }
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1599 if (linear_unchanged)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1600 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1601 gl_list_node_t node_for_insert =
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1602 result_entries_pointers[k_first];
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1603 ssize_t j;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1604 size_t i;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1605 for (j = edit->j2; j >= edit->j1; j--)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1606 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1607 struct entry *new_entry = modified_file.entries[j];
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1608 gl_list_add_before (result_entries, node_for_insert, new_entry);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1609 }
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1610 for (i = edit->i1; i <= edit->i2; i++)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1611 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1612 ssize_t k = entries_mapping_get (&mapping, i);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1613 ASSERT (k >= 0);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1614 ASSERT (entry_equals (ancestor_file.entries[i],
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1615 mainstream_file.entries[k]));
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1616 gl_list_node_set_value (result_entries,
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1617 result_entries_pointers[k],
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1618 &empty_entry);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1619 }
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1620 done = true;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1621 }
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1622 }
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1623 }
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1624 if (!done)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1625 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1626 struct conflict *c = XMALLOC (struct conflict);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1627 size_t i, j;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1628 c->num_old_entries = edit->i2 - edit->i1 + 1;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1629 c->old_entries =
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1630 XNMALLOC (c->num_old_entries, struct entry *);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1631 for (i = edit->i1; i <= edit->i2; i++)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1632 c->old_entries[i - edit->i1] = ancestor_file.entries[i];
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1633 c->num_modified_entries = edit->j2 - edit->j1 + 1;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1634 c->modified_entries =
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1635 XNMALLOC (c->num_modified_entries, struct entry *);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1636 for (j = edit->j1; j <= edit->j2; j++)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1637 c->modified_entries[j - edit->j1] = modified_file.entries[j];
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1638 gl_list_add_last (result_conflicts, c);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1639 }
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1640 }
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1641 break;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1642 }
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1643 }
9690
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1644 }
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1645
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1646 /* Output the result. */
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1647 {
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1648 FILE *fp = fopen (destination_file_name, "w");
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1649 if (fp == NULL)
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1650 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1651 fprintf (stderr, "could not write file '%s'\n", destination_file_name);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1652 exit (EXIT_FAILURE);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1653 }
9690
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1654
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1655 /* Output the conflicts at the top. */
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1656 {
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1657 size_t n = gl_list_size (result_conflicts);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1658 size_t i;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1659 for (i = 0; i < n; i++)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1660 conflict_write (fp, (struct conflict *) gl_list_get_at (result_conflicts, i));
9690
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1661 }
9714
5122118a6300 Speed up by 10%.
Bruno Haible <bruno@clisp.org>
parents: 9713
diff changeset
1662 /* Output the modified and unmodified entries, in order. */
9690
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1663 {
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1664 gl_list_iterator_t iter = gl_list_iterator (result_entries);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1665 const void *elt;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1666 gl_list_node_t node;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1667 while (gl_list_iterator_next (&iter, &elt, &node))
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1668 entry_write (fp, (struct entry *) elt);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1669 gl_list_iterator_free (&iter);
9690
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1670 }
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1671
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1672 if (fwriteerror (fp))
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1673 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1674 fprintf (stderr, "error writing to file '%s'\n", destination_file_name);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1675 exit (EXIT_FAILURE);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11707
diff changeset
1676 }
9690
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1677 }
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1678
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1679 exit (gl_list_size (result_conflicts) > 0 ? EXIT_FAILURE : EXIT_SUCCESS);
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1680 }
521de8c5a745 New module 'git-merge-changelog'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1681 }