diff --git a/tools/wt-worktree/tests/test_git.py b/tools/wt-worktree/tests/test_git.py index 0a3a5ea..d4f160d 100644 --- a/tools/wt-worktree/tests/test_git.py +++ b/tools/wt-worktree/tests/test_git.py @@ -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" diff --git a/tools/wt-worktree/wt/git.py b/tools/wt-worktree/wt/git.py index 19e73c0..7e1612f 100644 --- a/tools/wt-worktree/wt/git.py +++ b/tools/wt-worktree/wt/git.py @@ -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) + 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) + 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. diff --git a/tools/wt-worktree/wt/worktree.py b/tools/wt-worktree/wt/worktree.py index 8752b6f..2549ebb 100644 --- a/tools/wt-worktree/wt/worktree.py +++ b/tools/wt-worktree/wt/worktree.py @@ -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/ - 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) 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 + 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) + else: + # Remote doesn't exist yet, configure push target instead + git.configure_push_remote(branch, "origin", branch, wt_path) + except git.GitError: + # If this fails, user can still push with -u flag pass return wt_path