1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
|
/*
* Copyright (C) 2009 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import java.util.List;
import java.util.UUID;
/**
* Download two versions of Apache Harmony from their SVN version, and use it
* to perform a three-way merge with Dalvik.
*/
public class PullHarmonyCode {
private final int currentVersion;
private final int targetVersion;
public PullHarmonyCode(int currentVersion, int targetVersion) {
this.currentVersion = currentVersion;
this.targetVersion = targetVersion;
}
public void pull(Module module) {
String path = module.path();
String svnOldBranch = path + "_" + currentVersion;
String svnNewBranch = path + "_" + targetVersion;
String dalvikBranch = path + "_dalvik";
Git git = new Git();
Filesystem filesystem = new Filesystem();
Svn svn = new Svn();
// Assume we're starting with the current Dalvik code. Tuck this away
// somewhere while we rewrite history.
String temp = "/tmp/" + UUID.randomUUID();
filesystem.mkdir(temp);
// To prepare a three-way-merge, we need a common starting point: the
// time at which Dalvik and Harmony were most the same. We'll use the
// previous Harmony SVN code as this starting point. We grab the old
// code from their repository, and commit it as a git branch.
System.out.print("Creating branch " + svnOldBranch + "...");
git.branch(svnOldBranch);
filesystem.move(path, temp + "/" + path);
svn.checkOut(currentVersion, module.getSvnBaseUrl() + "/" + path);
filesystem.rm(filesystem.find(path, ".svn"));
for (MappedDirectory mappedDirectory : module.getMappedDirectories()) {
filesystem.moveContents(mappedDirectory.svnPath(), mappedDirectory.gitPath());
}
git.rm(git.listDeleted());
git.add(path);
git.commit(svnOldBranch);
System.out.println("done");
// Create a branch that's derived from the starting point. It will
// contain all of the changes Harmony has made from then until now.
System.out.print("Creating branch " + svnNewBranch + "...");
git.branch(svnNewBranch, svnOldBranch);
filesystem.rm(path);
svn.checkOut(targetVersion, module.getSvnBaseUrl() + "/" + path);
filesystem.rm(filesystem.find(path, ".svn"));
for (MappedDirectory mappedDirectory : module.getMappedDirectories()) {
filesystem.moveContents(mappedDirectory.svnPath(), mappedDirectory.gitPath());
}
git.rm(git.listDeleted());
git.add(path);
git.commit(svnNewBranch);
System.out.println("done");
// Create another branch that's derived from the starting point. It will
// contain all of the changes Dalvik has made from then until now.
System.out.print("Creating branch " + dalvikBranch + "...");
git.branch(dalvikBranch, svnOldBranch);
filesystem.rm(path);
filesystem.move(temp + "/" + path, path);
git.rm(git.listDeleted());
git.add(path);
git.commit(dalvikBranch);
System.out.println("done");
// Merge the two sets of changes together: Harmony's and Dalvik's. By
// initializing a common starting point, git can make better decisions
// when the two new versions differ. For example, if today's Dalvik has
// a method that today's Harmony does not, it may be because Dalvik
// added it, or because Harmony deleted it!
System.out.println("Merging " + svnNewBranch + " into " + dalvikBranch + ":");
List<String> mergeResults = git.merge(svnNewBranch);
for (String mergeResult : mergeResults) {
System.out.print(" ");
System.out.println(mergeResult);
}
}
public static void main(String[] args) {
if (args.length < 3) {
printUsage();
return;
}
int currentSvnRev = Integer.parseInt(args[0]);
int targetSvnRev = Integer.parseInt(args[1]);
if (currentSvnRev < 527399 || targetSvnRev <= currentSvnRev) {
System.out.println("Invalid SVN revision range: "
+ currentSvnRev + ".." + targetSvnRev);
return;
}
Module module = Module.VALUES.get(args[2]);
if (module == null) {
System.out.println("No such module: " + args[2]);
return;
}
PullHarmonyCode puller = new PullHarmonyCode(currentSvnRev, targetSvnRev);
puller.pull(module);
}
private static void printUsage() {
System.out.println("This tool will prepare a three-way merge between the latest Harmony");
System.out.println("the latest Dalvik, and their common ancestor. It downloads both old");
System.out.println("and new versions of Harmony code from SVN for better merge results.");
System.out.println();
System.out.println("Usage: PullHarmonyCode <current_rev> <target_rev> <module>...");
System.out.println();
System.out.println(" <current_rev> is the SVN revision of the Harmony code that was");
System.out.println(" most recently integrated into Dalvik. This should");
System.out.println(" be a number greater than 527399. The current");
System.out.println(" revision for each module is tracked at");
System.out.println(" http://go/dalvik/harmony");
System.out.println();
System.out.println(" <target_rev> is the SVN revision of the Harmony code to be");
System.out.println(" merged into Dalvik. This should be a number greater");
System.out.println(" than <current_rev>. The latest Harmony revision is");
System.out.println(" tracked at");
System.out.println(" http://svn.apache.org/viewvc/harmony/?root=Apache-SVN");
System.out.println();
System.out.println(" <module> is one of " + Module.VALUES.keySet());
System.out.println();
System.out.println("This program must be executed from within the dalvik/libcore directory");
System.out.println("of an Android git client. Such a client must be synced and contain no");
System.out.println("uncommitted changes. Upon termination, a new Git branch with the");
System.out.println("integrated changes will be active. This branch may require some manual");
System.out.println("merging.");
System.out.println();
System.out.println("Example usage:");
System.out.println(" java -cp ../../out/host/linux-x86/framework/integrate.jar PullAndroidCode \\");
System.out.println(" 527399 802921 security");
}
}
|