From 62adff2fc91a26086cb4719f362e084e226b173c Mon Sep 17 00:00:00 2001 From: Jim Fitzpatrick Date: Sat, 18 Jul 2026 22:53:44 +0100 Subject: [PATCH] UPDATE: Number of configuration settings This was all done in the hope to fix the bug reported in https://github.com/Boomatang/git-grab/issues/80 Signed-off-by: Jim Fitzpatrick --- .../unreleased/Added-20260718-224631.yaml | 3 + .../unreleased/Added-20260718-225021.yaml | 3 + .../unreleased/Fixed-20260718-225111.yaml | 3 + src/main.zig | 16 +++ src/root.zig | 112 ++++++++++++++++++ 5 files changed, 137 insertions(+) create mode 100644 .changes/unreleased/Added-20260718-224631.yaml create mode 100644 .changes/unreleased/Added-20260718-225021.yaml create mode 100644 .changes/unreleased/Fixed-20260718-225111.yaml diff --git a/.changes/unreleased/Added-20260718-224631.yaml b/.changes/unreleased/Added-20260718-224631.yaml new file mode 100644 index 0000000..874b023 --- /dev/null +++ b/.changes/unreleased/Added-20260718-224631.yaml @@ -0,0 +1,3 @@ +kind: Added +body: Configure the logAllRef on worktree configurations. This is disable by default of bare configurations. +time: 2026-07-18T22:46:31.51832434+01:00 diff --git a/.changes/unreleased/Added-20260718-225021.yaml b/.changes/unreleased/Added-20260718-225021.yaml new file mode 100644 index 0000000..ba0a7c2 --- /dev/null +++ b/.changes/unreleased/Added-20260718-225021.yaml @@ -0,0 +1,3 @@ +kind: Added +body: Configure autoSetupMerge on branches. This is a heavy handed configuration, but hoping to solve future problems. +time: 2026-07-18T22:50:21.658313086+01:00 diff --git a/.changes/unreleased/Fixed-20260718-225111.yaml b/.changes/unreleased/Fixed-20260718-225111.yaml new file mode 100644 index 0000000..334d35f --- /dev/null +++ b/.changes/unreleased/Fixed-20260718-225111.yaml @@ -0,0 +1,3 @@ +kind: Fixed +body: Fix the local tracking of remote branches on initial cloning into a worktree. +time: 2026-07-18T22:51:11.163885686+01:00 diff --git a/src/main.zig b/src/main.zig index af7330f..33c74b3 100644 --- a/src/main.zig +++ b/src/main.zig @@ -239,9 +239,25 @@ fn worktree(allocator: std.mem.Allocator, io: std.Io, project: grab.Project, opt std.log.err("unhandled error: {any}", .{err}); return err; }; + + grab.setLogAllRef(allocator, io, root) catch |err| { + std.log.err("unhandled error: {any}", .{err}); + return err; + }; + + grab.setAutoSetupMerge(allocator, io, root) catch |err| { + std.log.err("unhandled error: {any}", .{err}); + return err; + }; + grab.fetchOrigin(allocator, io, root) catch |err| { std.log.err("unhandled error: {any}", .{err}); return err; }; + + grab.setLocalTracking(allocator, io, root) catch |err| { + std.log.err("unhandled error: {any}", .{err}); + return err; + }; } } diff --git a/src/root.zig b/src/root.zig index 6ae51b6..df1d636 100644 --- a/src/root.zig +++ b/src/root.zig @@ -274,6 +274,118 @@ pub fn fetchOrigin(allocator: std.mem.Allocator, io: std.Io, path: std.Io.Dir) ! } } +pub fn setLogAllRef(allocator: std.mem.Allocator, io: std.Io, path: std.Io.Dir) !void { + const _path = try path.realPathFileAlloc(io, ".", allocator); + defer allocator.free(_path); + std.log.debug("Configuring logAllRefUpdates", .{}); + const cmd = [_][]const u8{ "git", "-C", _path, "config", "core.logallrefupdates", "true" }; + const result = std.process.run(allocator, io, .{ + .argv = &cmd, + }) catch |err| { + std.log.err("Failed to run git config log all ref updates: {}", .{err}); + return err; + }; + defer { + allocator.free(result.stdout); + allocator.free(result.stderr); + } + + if (result.term.exited != 0) { + std.log.err("{s}", .{result.stderr}); + return error.runtime; + } +} + +pub fn setAutoSetupMerge(allocator: std.mem.Allocator, io: std.Io, path: std.Io.Dir) !void { + const _path = try path.realPathFileAlloc(io, ".", allocator); + defer allocator.free(_path); + const cmd = [_][]const u8{ "git", "-C", _path, "config", "branch.autoSetupMerge", "always" }; + std.log.debug("Configuring autoSetupMerge", .{}); + const result = std.process.run(allocator, io, .{ + .argv = &cmd, + }) catch |err| { + std.log.err("Failed to run git config auto Setup Merge: {}", .{err}); + return err; + }; + defer { + allocator.free(result.stdout); + allocator.free(result.stderr); + } + if (result.term.exited != 0) { + std.log.err("{s}", .{result.stderr}); + return error.runtime; + } +} + +pub fn setLocalTracking(allocator: std.mem.Allocator, io: std.Io, path: std.Io.Dir) !void { + const _path = try path.realPathFileAlloc(io, ".", allocator); + defer allocator.free(_path); + + const branch_cmd = [_][]const u8{ "git", "-C", _path, "branch", "--format=%(refname:short)" }; + std.log.debug("Getting list of git branches", .{}); + const branch_result = std.process.run(allocator, io, .{ + .argv = &branch_cmd, + }) catch |err| { + std.log.err("Failed to run git branch: {}", .{err}); + return err; + }; + + defer { + allocator.free(branch_result.stderr); + allocator.free(branch_result.stdout); + } + if (branch_result.term.exited != 0) { + std.log.err("{s}", .{branch_result.stderr}); + return error.runtime; + } + + var iter = std.mem.splitScalar(u8, branch_result.stdout, '\n'); + while (iter.next()) |line| { + if (line.len == 0) continue; + std.log.debug("Working with branch: {s}", .{line}); + + const remote = try std.fmt.allocPrint(allocator, "branch.{s}.remote", .{line}); + defer allocator.free(remote); + + const merge = try std.fmt.allocPrint(allocator, "branch.{s}.merge", .{line}); + defer allocator.free(merge); + + const head = try std.fmt.allocPrint(allocator, "refs/heads/{s}", .{line}); + defer allocator.free(head); + + const remote_cmd = [_][]const u8{ "git", "-C", _path, "config", remote, "origin" }; + const merge_cmd = [_][]const u8{ "git", "-C", _path, "config", merge, head }; + + std.log.debug("Setting up remotes for origin", .{}); + const remote_result = std.process.run(allocator, io, .{ .argv = &remote_cmd }) catch |err| { + std.log.err("Failed to run git config {s} origin", .{remote}); + return err; + }; + defer { + allocator.free(remote_result.stderr); + allocator.free(remote_result.stdout); + } + if (remote_result.term.exited != 0) { + std.log.err("{s}", .{remote_result.stderr}); + return error.runtime; + } + + std.log.debug("Setting up merge configuration", .{}); + const merge_result = std.process.run(allocator, io, .{ .argv = &merge_cmd }) catch |err| { + std.log.err("Failed to run git config {s} {s}", .{ merge, head }); + return err; + }; + defer { + allocator.free(merge_result.stderr); + allocator.free(merge_result.stdout); + } + if (merge_result.term.exited != 0) { + std.log.err("{s}", .{merge_result.stderr}); + return error.runtime; + } + } +} + test "input parsing GitHub" { const input = "git@github.com:Boomatang/git-grab.git"; const expect = Project{