Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Re-enable rebase current origin #116

Merged
merged 1 commit into from
Jul 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 7 additions & 18 deletions src/main/java/org/nqm/command/GitCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,11 @@

import static org.nqm.command.CommandVerticle.GIS_CONCAT_MODULES_NAME_OPT;
import static org.nqm.command.CommandVerticle.GIS_NO_PRINT_MODULES_NAME_OPT;
import static org.nqm.command.Wrapper.ORIGIN;
import static org.nqm.command.Wrapper.forEachModuleDo;
import static org.nqm.command.Wrapper.forEachModuleDoRebaseCurrent;
import static org.nqm.command.Wrapper.forEachModuleWith;
import static org.nqm.command.Wrapper.getCurrentBranchUnderPath;
import static org.nqm.config.GisConfig.currentDir;
import java.io.BufferedReader;
import java.io.FileOutputStream;
Expand All @@ -22,13 +25,10 @@
import java.util.function.Predicate;
import java.util.regex.Pattern;
import java.util.stream.Stream;
import org.nqm.GisException;
import org.nqm.config.GisConfig;
import org.nqm.config.GisLog;
import org.nqm.utils.GisProcessUtils;
import org.nqm.model.GisSort;
import org.nqm.utils.GisStringUtils;
import org.nqm.utils.StdOutUtils;
import org.nqm.model.GisSort;
import picocli.CommandLine.Command;
import picocli.CommandLine.Option;
import picocli.CommandLine.Parameters;
Expand All @@ -37,7 +37,6 @@ public class GitCommand {

private static final String CHECKOUT = "checkout";
private static final String FETCHED_AT = "(fetched at: %s)";
private static final String ORIGIN = "origin";
private static final Path TMP_FILE = Path.of("/", "tmp", "gis_fetch" + currentDir().replace("/", "_"));

static final String GIS_AUTOCOMPLETE_FILE = "_gis";
Expand Down Expand Up @@ -130,8 +129,8 @@ void fetchStatus(@Option(names = "--sort",

@Command(name = "rebase-current-origin", aliases = "ru",
description = "Reapply commits on top of current repositories' origin")
void rebaseCurrentOrigin() {
throw new GisException("this function is in progress");
void rebaseCurrentOrigin() throws IOException {
forEachModuleDoRebaseCurrent();
}

@Command(name = "rebase-origin", aliases = "re", description = "Reapply commits on top of other base tip")
Expand Down Expand Up @@ -298,21 +297,11 @@ private static Stream<String> streamOf(String[] input) {
return Stream.of(input).map(String::trim).distinct();
}

private String getCurrentBranchUnderPath(Path path) throws IOException {
var result = GisProcessUtils.quickRun(path.toFile(), GisConfig.GIT_HOME_DIR, "branch", "--show-current");
return result.output().trim();
}

private boolean isSameBranchUnderPath(String branch, Path path) {
if (GisStringUtils.isBlank(branch)) {
return false;
}
try {
return branch.equals(getCurrentBranchUnderPath(path));
} catch (IOException e) {
GisLog.debug(e);
throw new GisException(e.getMessage());
}
return branch.equals(getCurrentBranchUnderPath(path));
}

private boolean isConfirmed(String question) throws IOException {
Expand Down
63 changes: 55 additions & 8 deletions src/main/java/org/nqm/command/Wrapper.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,22 @@
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executors;
import java.util.function.Consumer;
import java.util.function.Predicate;
import java.util.stream.Stream;
import org.nqm.GisException;
import org.nqm.config.GisConfig;
import org.nqm.config.GisLog;
import org.nqm.model.GisProcessDto;
import org.nqm.utils.GisProcessUtils;
import org.nqm.utils.StdOutUtils;

public final class Wrapper {

private Wrapper() {}

public static final String ORIGIN = "origin";

private static File isFileExist(File f) {
return f.exists() ? f : null;
}
Expand All @@ -44,15 +50,18 @@ private static File getFileMarker() {
return gitModulesFilePath;
}

public static Queue<String> forEachModuleWith(Predicate<Path> pred, String... args)
throws IOException {
public static Queue<String> forEachModuleDo(String... args) throws IOException {
return forEachModuleWith(p -> true, args);
}

public static Queue<String> forEachModuleWith(Predicate<Path> pred, String... args) throws IOException {
var gitModulesFilePath = getFileMarker();
var currentDir = currentDir();
var output = new ConcurrentLinkedQueue<String>();
try (var exe = Executors.newVirtualThreadPerTaskExecutor()) {
Optional.of(Path.of(currentDir))
.filter(pred)
.ifPresent(root -> exe.submit(() -> output.add(CommandVerticle.execute(root, args))));
Consumer<Path> consume = path -> exe.submit(() -> output.add(CommandVerticle.execute(path, args)));
Optional.of(Path.of(currentDir)).filter(pred).ifPresent(consume);

Files.readAllLines(gitModulesFilePath.toPath()).stream()
.map(String::trim)
.filter(s -> s.startsWith("path"))
Expand All @@ -66,12 +75,50 @@ public static Queue<String> forEachModuleWith(Predicate<Path> pred, String... ar
return false;
})
.filter(pred)
.forEach(dir -> exe.submit(() -> output.add(CommandVerticle.execute(dir, args))));
.forEach(consume);
}
return output;
}

public static Queue<String> forEachModuleDo(String... args) throws IOException {
return forEachModuleWith(p -> true, args);
public static void forEachModuleDoRebaseCurrent() throws IOException {
var gitModulesFilePath = getFileMarker();
var currentDir = currentDir();

try (var exe = Executors.newVirtualThreadPerTaskExecutor()) {
Consumer<Path> consume = path -> exe.submit(() -> {
var args = new String[] {"rebase", "%s/%s".formatted(ORIGIN, getCurrentBranchUnderPath(path))};
CommandVerticle.execute(path, args);
});

consume.accept(Path.of(currentDir));

Files.readAllLines(gitModulesFilePath.toPath()).stream()
.map(String::trim)
.filter(s -> s.startsWith("path"))
.map(s -> s.replace("path = ", ""))
.map(dir -> Path.of(currentDir, dir))
.filter(dir -> {
if (dir.toFile().exists()) {
return true;
}
StdOutUtils.errln("directory '%s' does not exist, will be ignored!".formatted("" + dir));
return false;
})
.forEach(consume);
}
}

public static String getCurrentBranchUnderPath(Path path) {
GisProcessDto result;
try {
result = GisProcessUtils.quickRun(path.toFile(), GisConfig.GIT_HOME_DIR, "branch", "--show-current");
} catch (IOException e) {
GisLog.debug(e);
throw new GisException(e.getMessage());
}
if (result != null) {
return result.output().trim();
}
return "";
}
}
71 changes: 71 additions & 0 deletions src/test/java/org/nqm/command/GitCommandIntTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -489,4 +489,75 @@ void stashPop_OK() throws IOException {
"(use \"git restore --staged <file>...\" to unstage)",
"new file: filescramble1");
}

@Test
void rebaseCurrentOrigin() throws IOException {
// given:
var repos = create_clone_gitRepositories("ali_4_x", "ali_5_xx", "ali_6_xxx");
gis.init();
commitFile(repos);
commitFile(repos);
gis.push("master", true, true, true);
resetHead1(repos);
cleanUntrackedFiles(repos);
resetOutputStreamTest();

gis.status(true, null);
assertThat(stripColors.apply(outCaptor.toString())).containsOnly(
"" + tempPath.subpath(1, tempPath.getNameCount()),
"ali_4_x master[behind 1]",
"ali_5_xx master[behind 1]",
"ali_6_xxx master[behind 1]");

// when:
resetOutputStreamTest();
gis.rebaseCurrentOrigin();

// then:
gis.status(true, null);
assertThat(stripColors.apply(outCaptor.toString())).containsOnly(
"" + tempPath.subpath(1, tempPath.getNameCount()),
"ali_4_x master",
"ali_5_xx master",
"ali_6_xxx master");
}

@Test
void rebaseCurrentOrigin_withEachModuleHasDifferentBranch() throws IOException {
// given:
var repos = create_clone_gitRepositories("ali_4_x", "ali_5_xx", "ali_6_xxx");
gis.init();
commitFile(repos);
gis.push("master", true, true, true);
gis.spinOff("bbb4", "ali_4_x");
gis.spinOff("bbb5", "ali_5_xx");
gis.spinOff("bbb6", "ali_6_xxx");
commitFile(repos);
gis.push("bbb4", true, true, true);
gis.push("bbb5", true, true, true);
gis.push("bbb6", true, true, true);
resetHead1(repos);
cleanUntrackedFiles(repos);
resetOutputStreamTest();

gis.status(true, null);
assertThat(stripColors.apply(outCaptor.toString())).containsOnly(
"" + tempPath.subpath(1, tempPath.getNameCount()),
"ali_4_x bbb4[behind 1]",
"ali_5_xx bbb5[behind 1]",
"ali_6_xxx bbb6[behind 1]");

// when:
resetOutputStreamTest();
gis.rebaseCurrentOrigin();

// then:
gis.status(true, null);
assertThat(stripColors.apply(outCaptor.toString())).containsOnly(
"" + tempPath.subpath(1, tempPath.getNameCount()),
"ali_4_x bbb4",
"ali_5_xx bbb5",
"ali_6_xxx bbb6");
}

}
13 changes: 13 additions & 0 deletions src/test/java/org/nqm/helper/GitBaseTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -155,4 +155,17 @@ protected void scrambleFiles(List<Path> repos) {
}
});
}

protected void resetHead1(List<Path> repos) {
repos.forEach(repo -> {
git(repo, "reset", "HEAD~1");
});
}

protected void cleanUntrackedFiles(List<Path> repos) {
repos.forEach(repo -> {
git(repo, "clean", "-fd");
});
}

}