1
+'use strict';
2
+
3
+/* eslint-disable no-for-of-loops/no-for-of-loops */
4
+
5
+const {writeFileSync} = require('fs');
6
+const path = require('path');
7
+const {spawnSync} = require('child_process');
8
+const minimist = require('minimist');
9
+const tmp = require('tmp');
10
+
11
+const argv = minimist(process.argv.slice(2), {
12
+ boolean: ['reverse'],
13
+ default: {
14
+ 'base-ref': 'HEAD',
15
+ },
16
+});
17
+
18
+const baseRef = argv['base-ref'];
19
+const baseDir = argv['base-dir'];
20
+
21
+function resolvePath(file) {
22
+ return baseDir !== undefined ? path.join(baseDir, file) : file;
23
+}
24
+
25
+function getTransforms() {
26
+ const old = argv.old;
27
+ const base = argv.base;
28
+ const _new = argv.new;
29
+ if (old !== undefined) {
30
+ if (_new === undefined) {
31
+ throw Error('Cannot provide --old without also providing --new');
32
+ }
33
+ const oldPath = resolvePath(old);
34
+ const newPath = resolvePath(_new);
35
+
36
+ let basePath;
37
+ let fromPath;
38
+ let toPath;
39
+ if (argv.reverse) {
40
+ fromPath = oldPath;
41
+ toPath = newPath;
42
+ basePath = base !== undefined ? resolvePath(basePath) : oldPath;
43
+ } else {
44
+ fromPath = newPath;
45
+ toPath = oldPath;
46
+ basePath = base !== undefined ? resolvePath(basePath) : newPath;
47
+ }
48
+
49
+ return [
50
+ {
51
+ base: basePath,
52
+ from: fromPath,
53
+ to: toPath,
54
+ },
55
+ ];
56
+ } else if (_new !== undefined) {
57
+ throw Error('Cannot provide --new without also providing --old');
58
+ }
59
+ return argv._.map(filename => {
60
+ const oldPath = resolvePath(filename + '.old.js');
61
+ const newPath = resolvePath(filename + '.new.js');
62
+
63
+ let basePath;
64
+ let fromPath;
65
+ let toPath;
66
+ if (argv.reverse) {
67
+ fromPath = oldPath;
68
+ toPath = newPath;
69
+ basePath = base !== undefined ? resolvePath(basePath) : oldPath;
70
+ } else {
71
+ fromPath = newPath;
72
+ toPath = oldPath;
73
+ basePath = base !== undefined ? resolvePath(basePath) : newPath;
74
+ }
75
+ return {
76
+ base: basePath,
77
+ from: fromPath,
78
+ to: toPath,
79
+ };
80
+ });
81
+}
82
+
83
+for (const {base: baseFilename, from, to} of getTransforms()) {
84
+ // Write the base file contents to a temporary file
85
+ const gitShowResult = spawnSync(
86
+ 'git',
87
+ ['show', `${baseRef}:${baseFilename}`],
88
+ {
89
+ stdio: 'pipe',
90
+ }
91
+ );
92
+ if (gitShowResult.status !== 0) {
93
+ console.error('' + gitShowResult.stderr);
94
+ continue;
95
+ }
96
+
97
+ const baseFileContents = gitShowResult.stdout;
98
+ const base = tmp.fileSync().name;
99
+ writeFileSync(base, baseFileContents);
100
+
101
+ // Run the merge with `git merge-file`
102
+ const mergeFileResult = spawnSync('git', ['merge-file', to, base, from], {
103
+ stdio: 'pipe',
104
+ });
105
+
106
+ if (mergeFileResult.status !== 0) {
107
+ console.error('' + mergeFileResult.stderr);
108
+ }
109
+}