Skip to content
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
16 changes: 16 additions & 0 deletions tools/wt-worktree/tests/test_git.py
Original file line number Diff line number Diff line change
Expand Up @@ -143,3 +143,19 @@ def test_diff_trees(git_repo):
# Get diff
diff = git.diff_trees("HEAD~1", "HEAD", git_repo)
assert "file2.txt" in diff


def test_configure_push_remote(git_repo):
"""Test configuring push remote for a branch."""
# Create a new branch
git.create_branch("test-branch", "HEAD", git_repo)

# Configure push remote
git.configure_push_remote("test-branch", "origin", "test-branch", git_repo)

# Verify configuration was set
result = git.run_git(["config", "branch.test-branch.remote"], cwd=git_repo)
assert result.stdout.strip() == "origin"

result = git.run_git(["config", "branch.test-branch.merge"], cwd=git_repo)
assert result.stdout.strip() == "refs/heads/test-branch"
Comment on lines +148 to +161

Copilot AI Jan 18, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The test for configure_push_remote only verifies that the configuration is set correctly but doesn't test the main use case described in the PR: that it works even when the remote branch doesn't exist yet. Consider adding an assertion that attempts to run git push (or at least simulates it) to verify the configuration allows pushing without the -u flag.

Copilot uses AI. Check for mistakes.
24 changes: 24 additions & 0 deletions tools/wt-worktree/wt/git.py
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,30 @@ def set_upstream(branch: str, remote: str = "origin",
run_git(["branch", f"--set-upstream-to={remote}/{remote_branch}", branch], cwd=path)


def configure_push_remote(branch: str, remote: str = "origin",
remote_branch: Optional[str] = None, path: Optional[Path] = None):
"""
Configure where a branch should push to, even if remote branch doesn't exist yet.

This sets branch.{branch}.remote and branch.{branch}.merge so that 'git push'
will work without needing to specify the remote or use -u flag.

Args:
branch: Local branch name
remote: Remote name
remote_branch: Remote branch name (defaults to same as local)
Comment thread
dev-ankit marked this conversation as resolved.
path: Repository path to run git commands in
"""
if remote_branch is None:
remote_branch = branch

# Set the remote
run_git(["config", f"branch.{branch}.remote", remote], cwd=path)

# Set the merge target (what the branch tracks/pushes to)

Copilot AI Jan 18, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment "Set the merge target (what the branch tracks/pushes to)" is slightly misleading. The branch.{branch}.merge config is primarily used for pulling/fetching, not pushing. While setting both branch.{branch}.remote and branch.{branch}.merge does enable git push to work without flags, it would be more accurate to say "Set the upstream branch for pulling" or "Set the merge target (used for both pulling and to infer push target)".

Suggested change
# Set the merge target (what the branch tracks/pushes to)
# Set the upstream/merge target (used for pulling and to infer push target)

Copilot uses AI. Check for mistakes.
run_git(["config", f"branch.{branch}.merge", f"refs/heads/{remote_branch}"], cwd=path)


def list_worktrees(path: Optional[Path] = None) -> List[dict]:
"""
List all worktrees.
Expand Down
24 changes: 17 additions & 7 deletions tools/wt-worktree/wt/worktree.py
Original file line number Diff line number Diff line change
Expand Up @@ -170,15 +170,25 @@ def create_worktree(self, name: str, base: Optional[str] = None,
except git.GitError as e:
raise git.GitError(f"Failed to create worktree: {e}")

# Set upstream tracking if not detached
if not detached:
# Configure push remote if not detached
if not detached and create_branch:
try:
# Set upstream to origin/<branch>
remote_branch = branch
git.set_upstream(branch, "origin", remote_branch, self.repo_root)
# For new branches, configure where to push (so git push works without -u)
# This works even if remote branch doesn't exist yet
git.configure_push_remote(branch, "origin", branch, wt_path)

Copilot AI Jan 18, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For consistency with the set_upstream call on line 186, consider using self.repo_root instead of wt_path as the path parameter. While git config commands work from any worktree directory, using a consistent pattern makes the code more maintainable. The same applies to line 189.

Copilot uses AI. Check for mistakes.
except git.GitError:
# Upstream setting might fail if remote doesn't exist yet
# This is okay, user can push later
# If this fails, user can still push with -u flag
pass
Comment on lines +174 to +181

Copilot AI Jan 18, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new push remote configuration behavior introduced in create_worktree is not tested. Consider adding a test that verifies the branch.{branch}.remote and branch.{branch}.merge configuration is set correctly after creating a worktree with a new branch. This would ensure the main purpose of this PR (fixing git push in new worktrees) is properly tested at the integration level.

Copilot uses AI. Check for mistakes.
elif not detached:
try:
# For existing branches, check if remote branch exists and set upstream
if git.remote_branch_exists(branch, "origin", self.repo_root):
git.set_upstream(branch, "origin", branch, self.repo_root)

Copilot AI Jan 18, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For consistency with the other calls to configure_push_remote on lines 178 and 189, this should use wt_path instead of self.repo_root. While git branch --set-upstream-to can be run from anywhere in the repository, using the worktree path is more consistent and clearer in intent.

Suggested change
git.set_upstream(branch, "origin", branch, self.repo_root)
git.set_upstream(branch, "origin", branch, wt_path)

Copilot uses AI. Check for mistakes.
else:
# Remote doesn't exist yet, configure push target instead
git.configure_push_remote(branch, "origin", branch, wt_path)

Copilot AI Jan 18, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For consistency with the set_upstream call on line 186, consider using self.repo_root instead of wt_path as the path parameter. While git config commands work from any worktree directory, using a consistent pattern makes the code more maintainable.

Suggested change
git.configure_push_remote(branch, "origin", branch, wt_path)
git.configure_push_remote(branch, "origin", branch, self.repo_root)

Copilot uses AI. Check for mistakes.
except git.GitError:
# If this fails, user can still push with -u flag
pass
Comment on lines +182 to 192

Copilot AI Jan 18, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new push remote configuration behavior for existing branches is not tested. Consider adding a test that verifies the correct configuration is set when creating a worktree with an existing branch that has no remote branch yet. This would ensure both code paths (lines 185-189) are adequately tested.

Copilot uses AI. Check for mistakes.

return wt_path
Expand Down
Loading