pygitgo 1.8.1__tar.gz → 1.8.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {pygitgo-1.8.1/src/pygitgo.egg-info → pygitgo-1.8.2}/PKG-INFO +1 -1
- {pygitgo-1.8.1 → pygitgo-1.8.2}/pyproject.toml +1 -1
- {pygitgo-1.8.1 → pygitgo-1.8.2}/src/pygitgo/auth/account.py +3 -2
- {pygitgo-1.8.1 → pygitgo-1.8.2}/src/pygitgo/auth/manager.py +8 -10
- {pygitgo-1.8.1 → pygitgo-1.8.2}/src/pygitgo/auth/ssh_utils.py +14 -11
- {pygitgo-1.8.1 → pygitgo-1.8.2}/src/pygitgo/commands/config.py +4 -6
- {pygitgo-1.8.1 → pygitgo-1.8.2}/src/pygitgo/commands/git_branch.py +3 -4
- {pygitgo-1.8.1 → pygitgo-1.8.2}/src/pygitgo/commands/git_core.py +7 -3
- {pygitgo-1.8.1 → pygitgo-1.8.2}/src/pygitgo/commands/git_remote.py +5 -9
- {pygitgo-1.8.1 → pygitgo-1.8.2}/src/pygitgo/commands/init.py +6 -3
- {pygitgo-1.8.1 → pygitgo-1.8.2}/src/pygitgo/commands/jump.py +14 -18
- {pygitgo-1.8.1 → pygitgo-1.8.2}/src/pygitgo/commands/link.py +28 -24
- pygitgo-1.8.2/src/pygitgo/commands/new.py +66 -0
- {pygitgo-1.8.1 → pygitgo-1.8.2}/src/pygitgo/commands/pull.py +10 -2
- {pygitgo-1.8.1 → pygitgo-1.8.2}/src/pygitgo/commands/push.py +9 -6
- {pygitgo-1.8.1 → pygitgo-1.8.2}/src/pygitgo/commands/repo.py +41 -3
- {pygitgo-1.8.1 → pygitgo-1.8.2}/src/pygitgo/commands/staging.py +1 -1
- {pygitgo-1.8.1 → pygitgo-1.8.2}/src/pygitgo/commands/stash.py +12 -0
- {pygitgo-1.8.1 → pygitgo-1.8.2}/src/pygitgo/commands/state.py +5 -4
- {pygitgo-1.8.1 → pygitgo-1.8.2}/src/pygitgo/commands/undo.py +34 -29
- {pygitgo-1.8.1 → pygitgo-1.8.2}/src/pygitgo/commands/user.py +3 -2
- {pygitgo-1.8.1 → pygitgo-1.8.2}/src/pygitgo/main.py +2 -2
- {pygitgo-1.8.1 → pygitgo-1.8.2}/src/pygitgo/utils/bootstrap.py +1 -1
- pygitgo-1.8.1/src/pygitgo/utils/colors.py → pygitgo-1.8.2/src/pygitgo/utils/cli_io.py +16 -15
- pygitgo-1.8.2/src/pygitgo/utils/colors.py +6 -0
- {pygitgo-1.8.1 → pygitgo-1.8.2}/src/pygitgo/utils/config.py +1 -1
- {pygitgo-1.8.1 → pygitgo-1.8.2}/src/pygitgo/utils/executor.py +6 -8
- {pygitgo-1.8.1 → pygitgo-1.8.2}/src/pygitgo/utils/platform.py +3 -3
- {pygitgo-1.8.1 → pygitgo-1.8.2}/src/pygitgo/utils/update_checker.py +5 -5
- {pygitgo-1.8.1 → pygitgo-1.8.2/src/pygitgo.egg-info}/PKG-INFO +1 -1
- {pygitgo-1.8.1 → pygitgo-1.8.2}/src/pygitgo.egg-info/SOURCES.txt +5 -0
- {pygitgo-1.8.1 → pygitgo-1.8.2}/tests/test_account.py +1 -2
- pygitgo-1.8.2/tests/test_cli_io.py +51 -0
- {pygitgo-1.8.1 → pygitgo-1.8.2}/tests/test_config_command.py +7 -11
- pygitgo-1.8.2/tests/test_executor.py +92 -0
- {pygitgo-1.8.1 → pygitgo-1.8.2}/tests/test_git_branch.py +2 -3
- {pygitgo-1.8.1 → pygitgo-1.8.2}/tests/test_git_core.py +6 -8
- {pygitgo-1.8.1 → pygitgo-1.8.2}/tests/test_git_remote.py +13 -9
- {pygitgo-1.8.1 → pygitgo-1.8.2}/tests/test_init.py +0 -1
- pygitgo-1.8.2/tests/test_integration_git.py +73 -0
- {pygitgo-1.8.1 → pygitgo-1.8.2}/tests/test_jump.py +54 -4
- {pygitgo-1.8.1 → pygitgo-1.8.2}/tests/test_link.py +96 -7
- pygitgo-1.8.2/tests/test_main.py +116 -0
- {pygitgo-1.8.1 → pygitgo-1.8.2}/tests/test_manager.py +9 -10
- pygitgo-1.8.2/tests/test_new.py +90 -0
- {pygitgo-1.8.1 → pygitgo-1.8.2}/tests/test_platform.py +63 -62
- {pygitgo-1.8.1 → pygitgo-1.8.2}/tests/test_pull.py +15 -5
- {pygitgo-1.8.1 → pygitgo-1.8.2}/tests/test_push.py +20 -6
- {pygitgo-1.8.1 → pygitgo-1.8.2}/tests/test_repo.py +0 -1
- {pygitgo-1.8.1 → pygitgo-1.8.2}/tests/test_ssh_utils.py +37 -3
- {pygitgo-1.8.1 → pygitgo-1.8.2}/tests/test_staging.py +2 -4
- {pygitgo-1.8.1 → pygitgo-1.8.2}/tests/test_stash.py +8 -9
- {pygitgo-1.8.1 → pygitgo-1.8.2}/tests/test_state.py +83 -0
- {pygitgo-1.8.1 → pygitgo-1.8.2}/tests/test_undo.py +71 -38
- {pygitgo-1.8.1 → pygitgo-1.8.2}/tests/test_update_checker.py +2 -3
- pygitgo-1.8.1/src/pygitgo/commands/new.py +0 -21
- pygitgo-1.8.1/tests/test_new.py +0 -27
- {pygitgo-1.8.1 → pygitgo-1.8.2}/LICENSE +0 -0
- {pygitgo-1.8.1 → pygitgo-1.8.2}/README.md +0 -0
- {pygitgo-1.8.1 → pygitgo-1.8.2}/setup.cfg +0 -0
- {pygitgo-1.8.1 → pygitgo-1.8.2}/src/pygitgo/__init__.py +0 -0
- {pygitgo-1.8.1 → pygitgo-1.8.2}/src/pygitgo/auth/__init__.py +0 -0
- {pygitgo-1.8.1 → pygitgo-1.8.2}/src/pygitgo/commands/__init__.py +0 -0
- {pygitgo-1.8.1 → pygitgo-1.8.2}/src/pygitgo/exceptions.py +0 -0
- {pygitgo-1.8.1 → pygitgo-1.8.2}/src/pygitgo/utils/__init__.py +0 -0
- {pygitgo-1.8.1 → pygitgo-1.8.2}/src/pygitgo/utils/validators.py +0 -0
- {pygitgo-1.8.1 → pygitgo-1.8.2}/src/pygitgo.egg-info/dependency_links.txt +0 -0
- {pygitgo-1.8.1 → pygitgo-1.8.2}/src/pygitgo.egg-info/entry_points.txt +0 -0
- {pygitgo-1.8.1 → pygitgo-1.8.2}/src/pygitgo.egg-info/requires.txt +0 -0
- {pygitgo-1.8.1 → pygitgo-1.8.2}/src/pygitgo.egg-info/top_level.txt +0 -0
- {pygitgo-1.8.1 → pygitgo-1.8.2}/tests/test_bootstrap.py +0 -0
- {pygitgo-1.8.1 → pygitgo-1.8.2}/tests/test_config_utils.py +0 -0
- {pygitgo-1.8.1 → pygitgo-1.8.2}/tests/test_user.py +0 -0
- {pygitgo-1.8.1 → pygitgo-1.8.2}/tests/test_validators.py +0 -0
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "pygitgo"
|
|
7
|
-
version = "1.8.
|
|
7
|
+
version = "1.8.2"
|
|
8
8
|
description = "GitGo CLI - Your Fast Git Companion. Simplifies git push, link, stash, and user management."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = {text = "GPL-3.0-or-later"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
from pygitgo.utils.
|
|
1
|
+
from pygitgo.utils.cli_io import info, success, warning, error
|
|
2
2
|
from pygitgo.utils.executor import run_command
|
|
3
3
|
from pygitgo.exceptions import GitCommandError
|
|
4
|
+
from pygitgo.utils.colors import BLUE, RESET
|
|
4
5
|
|
|
5
6
|
|
|
6
7
|
def get_user():
|
|
@@ -24,7 +25,7 @@ def get_user():
|
|
|
24
25
|
def set_user(name, email):
|
|
25
26
|
run_command(["git", "config", "--global", "user.name", name])
|
|
26
27
|
run_command(["git", "config", "--global", "user.email", email])
|
|
27
|
-
success(
|
|
28
|
+
success("\nGit user configured successfully.")
|
|
28
29
|
print(f"{BLUE}Username{RESET} : {name}")
|
|
29
30
|
print(f"{BLUE}Email {RESET}: {email}")
|
|
30
31
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
from pygitgo.utils.
|
|
1
|
+
from pygitgo.utils.cli_io import info, success, warning, error
|
|
2
2
|
from pygitgo.utils.platform import get_platform
|
|
3
3
|
from pygitgo.utils.executor import run_command
|
|
4
4
|
from pygitgo.exceptions import GitCommandError
|
|
@@ -24,7 +24,7 @@ def login():
|
|
|
24
24
|
already_logged_in = key_path.exists()
|
|
25
25
|
ok_text = "Already logged in via GitGo." if already_logged_in else "GitHub connection verified."
|
|
26
26
|
|
|
27
|
-
if ssh_utils.check_connection(ok_text=ok_text):
|
|
27
|
+
if ssh_utils.check_connection(ok_text=ok_text, fail_text="Not connected to GitHub."):
|
|
28
28
|
if already_logged_in:
|
|
29
29
|
_configure_ssh_signing(key_path)
|
|
30
30
|
ensure_user_configure(default_username=ssh_utils.get_github_username())
|
|
@@ -63,9 +63,9 @@ def login():
|
|
|
63
63
|
print()
|
|
64
64
|
|
|
65
65
|
info("Copy the key above, then add it TWICE on GitHub:")
|
|
66
|
-
info(" 1. Authentication Key
|
|
67
|
-
info(" 2. Signing Key
|
|
68
|
-
info("Same key text for both.")
|
|
66
|
+
info(" 1. Authentication Key (for pushing and pulling)")
|
|
67
|
+
info(" 2. Signing Key (for Verified commits)")
|
|
68
|
+
info("Same key text for both entries.")
|
|
69
69
|
|
|
70
70
|
input("\nOnce you've copied the key, press Enter to open GitHub...")
|
|
71
71
|
|
|
@@ -76,8 +76,6 @@ def login():
|
|
|
76
76
|
"come back here and press Enter to verify the connection..."
|
|
77
77
|
)
|
|
78
78
|
|
|
79
|
-
ssh_utils.ensure_ssh_agent(ssh_utils.get_ssh_key_path())
|
|
80
|
-
|
|
81
79
|
ssh_utils.clear_ssh_cache()
|
|
82
80
|
|
|
83
81
|
if ssh_utils.check_connection(ok_text="Login successful. You are connected.", fail_text="SSH key not recognised by GitHub."):
|
|
@@ -117,16 +115,16 @@ def logout():
|
|
|
117
115
|
os.remove(pub_key_path)
|
|
118
116
|
|
|
119
117
|
try:
|
|
120
|
-
run_command(["git", "config", "--global", "--unset-all", "user.name"])
|
|
118
|
+
run_command(["git", "config", "--global", "--unset-all", "user.name"], loading_msg="Clearing Git username...", ok_text="Git username cleared.")
|
|
121
119
|
except GitCommandError:
|
|
122
120
|
pass
|
|
123
121
|
|
|
124
122
|
try:
|
|
125
|
-
run_command(["git", "config", "--global", "--unset-all", "user.email"])
|
|
123
|
+
run_command(["git", "config", "--global", "--unset-all", "user.email"], loading_msg="Clearing Git email...", ok_text="Git email cleared.")
|
|
126
124
|
except GitCommandError:
|
|
127
125
|
pass
|
|
128
126
|
|
|
129
|
-
success("User successfully
|
|
127
|
+
success("User successfully logged out.")
|
|
130
128
|
return True
|
|
131
129
|
|
|
132
130
|
except Exception as e:
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
from pygitgo.exceptions import GitCommandError, GitGoError
|
|
2
|
-
from pygitgo.utils.
|
|
2
|
+
from pygitgo.utils.cli_io import info, success, warning
|
|
3
3
|
from pygitgo.utils.platform import get_platform
|
|
4
4
|
from pygitgo.utils.executor import run_command
|
|
5
5
|
from pathlib import Path
|
|
@@ -115,6 +115,9 @@ def generate_ssh_key(email):
|
|
|
115
115
|
key_path.parent.mkdir(parents=True)
|
|
116
116
|
|
|
117
117
|
if key_path.exists():
|
|
118
|
+
from pygitgo.utils.cli_io import confirm
|
|
119
|
+
if not confirm(f"SSH key {key_path} already exists. Overwrite it? (y/n): ", destructive=True):
|
|
120
|
+
raise GitGoError("SSH key generation aborted. Please back up your existing key or configure it manually.")
|
|
118
121
|
os.remove(key_path)
|
|
119
122
|
if (key_path.parent / f"{key_path.name}.pub").exists():
|
|
120
123
|
os.remove(key_path.parent / f"{key_path.name}.pub")
|
|
@@ -135,7 +138,7 @@ def generate_ssh_key(email):
|
|
|
135
138
|
f"Details: {e}"
|
|
136
139
|
)
|
|
137
140
|
|
|
138
|
-
ensure_ssh_agent(key_path)
|
|
141
|
+
ensure_ssh_agent(key_path, quiet=True)
|
|
139
142
|
|
|
140
143
|
return key_path
|
|
141
144
|
|
|
@@ -162,7 +165,7 @@ def _try_ssh_add(key_path):
|
|
|
162
165
|
except (GitCommandError, OSError):
|
|
163
166
|
return False
|
|
164
167
|
|
|
165
|
-
def ensure_ssh_agent(key_path):
|
|
168
|
+
def ensure_ssh_agent(key_path, quiet=False):
|
|
166
169
|
if _try_ssh_add(key_path):
|
|
167
170
|
return True
|
|
168
171
|
|
|
@@ -180,16 +183,16 @@ def ensure_ssh_agent(key_path):
|
|
|
180
183
|
if _try_ssh_add(key_path):
|
|
181
184
|
return True
|
|
182
185
|
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
186
|
+
if not quiet:
|
|
187
|
+
warning("SSH agent is not running. Key may not persist across sessions.")
|
|
188
|
+
info("To fix this permanently, run in PowerShell (as Administrator):")
|
|
189
|
+
info(" Set-Service ssh-agent -StartupType Automatic")
|
|
190
|
+
info(" Start-Service ssh-agent")
|
|
188
191
|
|
|
189
192
|
else:
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
+
if not quiet:
|
|
194
|
+
warning("SSH agent is not running. Key may not persist across sessions.")
|
|
195
|
+
info("Run: eval $(ssh-agent) && ssh-add")
|
|
193
196
|
|
|
194
197
|
return False
|
|
195
198
|
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
from pygitgo.utils.config import get_config, set_config
|
|
2
|
-
from pygitgo.utils.
|
|
2
|
+
from pygitgo.utils.cli_io import warning, info
|
|
3
|
+
from pygitgo.exceptions import GitGoError
|
|
3
4
|
|
|
4
5
|
|
|
5
6
|
def config_operation(args):
|
|
@@ -10,14 +11,11 @@ def config_operation(args):
|
|
|
10
11
|
|
|
11
12
|
VALID_KEYS = ["default-branch", "default-message"]
|
|
12
13
|
if key not in VALID_KEYS:
|
|
13
|
-
|
|
14
|
-
warning(f"Valid keys are: {', '.join(VALID_KEYS)}\n")
|
|
15
|
-
return
|
|
14
|
+
raise GitGoError(f"Invalid configuration key: '{key}'. Valid keys are: {', '.join(VALID_KEYS)}")
|
|
16
15
|
|
|
17
16
|
if action == 'set':
|
|
18
17
|
if not value:
|
|
19
|
-
|
|
20
|
-
return
|
|
18
|
+
raise GitGoError("You must provide a value to set!")
|
|
21
19
|
set_config(key, value)
|
|
22
20
|
elif action == 'get':
|
|
23
21
|
current_value = get_config(key, None)
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
from pygitgo.utils.
|
|
1
|
+
from pygitgo.utils.cli_io import success, error, info, confirm
|
|
2
2
|
from pygitgo.exceptions import GitCommandError, GitGoError
|
|
3
3
|
from pygitgo.utils.executor import run_command
|
|
4
4
|
from pygitgo.utils.config import get_config
|
|
@@ -44,9 +44,8 @@ def git_new_branch(branch, ok_text=None):
|
|
|
44
44
|
if current == branch:
|
|
45
45
|
info(f"Already on branch '{branch}'. Continuing...")
|
|
46
46
|
else:
|
|
47
|
-
error(f"Failed to create branch '{branch}'
|
|
48
|
-
|
|
49
|
-
if choice == "y":
|
|
47
|
+
error(f"Failed to create branch '{branch}'. It may already exist.")
|
|
48
|
+
if confirm(f"Switch to the existing branch '{branch}' instead? (y/n): "):
|
|
50
49
|
from pygitgo.commands.jump import jump_operation
|
|
51
50
|
jump_operation(Namespace(branch=branch))
|
|
52
51
|
else:
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
from pygitgo.auth.ssh_utils import convert_https_to_ssh, get_ssh_key_path, is_ssh_url, check_connection
|
|
2
|
-
from pygitgo.utils.colors import info, success, warning, error
|
|
3
2
|
from pygitgo.exceptions import GitGoError, GitCommandError
|
|
4
3
|
from pygitgo.auth.account import sanitize_signing_config
|
|
5
4
|
from pygitgo.commands.git_remote import handle_rebase
|
|
6
5
|
from pygitgo.utils.config import get_default_branch
|
|
7
6
|
from pygitgo.utils.executor import run_command
|
|
7
|
+
from pygitgo.utils.cli_io import info, warning
|
|
8
8
|
import os
|
|
9
9
|
|
|
10
10
|
|
|
@@ -19,7 +19,9 @@ def _get_signing_flags():
|
|
|
19
19
|
]
|
|
20
20
|
|
|
21
21
|
|
|
22
|
-
def git_commit(commit_message, loading_msg="
|
|
22
|
+
def git_commit(commit_message, loading_msg="Committing changes...", skip_staging=False, ok_text=None):
|
|
23
|
+
if not ok_text:
|
|
24
|
+
ok_text = "Changes committed."
|
|
23
25
|
try:
|
|
24
26
|
status_result = run_command(["git", "status", "--porcelain"])
|
|
25
27
|
if not status_result.strip():
|
|
@@ -30,7 +32,7 @@ def git_commit(commit_message, loading_msg="Commiting changes...", skip_staging=
|
|
|
30
32
|
sanitize_signing_config()
|
|
31
33
|
|
|
32
34
|
if not skip_staging:
|
|
33
|
-
run_command(["git", "add", "."], loading_msg="Staging files...")
|
|
35
|
+
run_command(["git", "add", "."], loading_msg="Staging files...", ok_text="Files staged.")
|
|
34
36
|
|
|
35
37
|
clean_message = commit_message.strip('"\'')
|
|
36
38
|
|
|
@@ -61,6 +63,8 @@ def git_init(ok_text=None):
|
|
|
61
63
|
|
|
62
64
|
|
|
63
65
|
def git_push(branch, ok_text=None):
|
|
66
|
+
if not ok_text:
|
|
67
|
+
ok_text = f"Pushed to remote branch '{branch}'."
|
|
64
68
|
try:
|
|
65
69
|
remote_url = run_command(["git", "remote", "get-url", "origin"]).strip()
|
|
66
70
|
except GitCommandError:
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
from pygitgo.utils.colors import info, success, warning, error
|
|
2
1
|
from pygitgo.exceptions import GitCommandError, GitGoError
|
|
2
|
+
from pygitgo.utils.cli_io import info, warning, error
|
|
3
3
|
from pygitgo.utils.executor import run_command
|
|
4
4
|
|
|
5
5
|
|
|
@@ -15,23 +15,19 @@ def add_remote_origin(repo_url):
|
|
|
15
15
|
|
|
16
16
|
|
|
17
17
|
def confirm_remote_link(ok_text=None):
|
|
18
|
+
if not ok_text:
|
|
19
|
+
ok_text = "Remote is reachable."
|
|
18
20
|
try:
|
|
19
|
-
if not ok_text:
|
|
20
|
-
ok_text = "Remote is reachable."
|
|
21
21
|
run_command(["git", "ls-remote", "origin"], loading_msg="Testing connection to remote...", ok_text=ok_text)
|
|
22
22
|
return True
|
|
23
23
|
except GitCommandError:
|
|
24
|
-
error("Connection failed — verify the URL and your SSH key.")
|
|
25
24
|
info("Run: git remote -v to inspect your current remote.")
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
25
|
+
raise GitGoError("Connection failed — verify the URL and your SSH key.")
|
|
30
26
|
|
|
31
27
|
|
|
32
28
|
def check_and_sync_branch(branch):
|
|
33
29
|
try:
|
|
34
|
-
run_command(["git", "fetch", "origin"], loading_msg="Checking if branch is up to date...")
|
|
30
|
+
run_command(["git", "fetch", "origin"], loading_msg="Checking if branch is up to date...", ok_text="Remote fetched.")
|
|
35
31
|
|
|
36
32
|
try:
|
|
37
33
|
local_commit = run_command(["git", "rev-parse", branch])
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
from pygitgo.commands.git_core import git_init
|
|
2
|
-
from pygitgo.utils.colors import info, success
|
|
3
2
|
from pygitgo.exceptions import GitGoError
|
|
3
|
+
from pygitgo.utils.cli_io import info
|
|
4
4
|
import urllib.request
|
|
5
5
|
import urllib.error
|
|
6
6
|
import zipfile
|
|
@@ -292,7 +292,7 @@ def _scaffold_language(lang, target_dir, name):
|
|
|
292
292
|
info(f"Created {name}.csproj and Program.cs")
|
|
293
293
|
|
|
294
294
|
|
|
295
|
-
def init_operation(args):
|
|
295
|
+
def init_operation(args, standalone=False):
|
|
296
296
|
target_dir = args.name
|
|
297
297
|
|
|
298
298
|
if os.path.exists(target_dir) and os.listdir(target_dir):
|
|
@@ -311,7 +311,10 @@ def init_operation(args):
|
|
|
311
311
|
os.chdir(target_dir)
|
|
312
312
|
git_init(ok_text=f"Initialized empty Git repository in {os.path.abspath('.')}")
|
|
313
313
|
|
|
314
|
-
|
|
314
|
+
if standalone:
|
|
315
|
+
from pygitgo.utils.cli_io import banner
|
|
316
|
+
banner("LOCAL SCAFFOLD CONSTRUCTED.", "PROJECT STRUCTURE AND REPOSITORY INITIALIZED.")
|
|
317
|
+
info(f"Next steps:\n cd {target_dir}\n gitgo repo\n gitgo link <url>")
|
|
315
318
|
|
|
316
319
|
except Exception as e:
|
|
317
320
|
if os.path.exists(target_dir) and not os.listdir(target_dir):
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
+
from pygitgo.utils.cli_io import warning, info, success, error, confirm, banner
|
|
1
2
|
from pygitgo.commands.git_branch import (
|
|
2
3
|
is_branch_exist, get_current_branch, git_new_branch, get_main_branch,
|
|
3
4
|
)
|
|
4
5
|
from pygitgo.commands.stash import (
|
|
5
6
|
git_stash_pop, git_stash_push, git_stash_apply, git_stash_drop
|
|
6
7
|
)
|
|
7
|
-
from pygitgo.utils.colors import warning, info, success, error
|
|
8
8
|
from pygitgo.exceptions import GitCommandError, GitGoError
|
|
9
9
|
from pygitgo.utils.executor import run_command
|
|
10
10
|
import sys
|
|
@@ -19,7 +19,7 @@ def undo_jump_operation(original_branch, stashed_code, created_branch=None):
|
|
|
19
19
|
except GitCommandError:
|
|
20
20
|
warning(f"Could not delete branch '{created_branch}'. Remove it manually with: git branch -D {created_branch}")
|
|
21
21
|
else:
|
|
22
|
-
run_command(["git", "reset", "--hard", "HEAD"], loading_msg="Canceling... Putting your files back exactly how they were...")
|
|
22
|
+
run_command(["git", "reset", "--hard", "HEAD"], loading_msg="Canceling... Putting your files back exactly how they were...", ok_text="Files restored to original state.")
|
|
23
23
|
ok_text = None if stashed_code else f"Canceled safely. Back on '{original_branch}'."
|
|
24
24
|
run_command(['git', 'checkout', original_branch], loading_msg=f"Jumping you back to the original branch '{original_branch}'...", ok_text=ok_text)
|
|
25
25
|
|
|
@@ -31,7 +31,7 @@ def undo_jump_operation(original_branch, stashed_code, created_branch=None):
|
|
|
31
31
|
|
|
32
32
|
def _jump_interrupt_cleanup(original_branch, stashed_code, created_branch):
|
|
33
33
|
try:
|
|
34
|
-
run_command(["git", "rebase", "--abort"])
|
|
34
|
+
run_command(["git", "rebase", "--abort"], loading_msg="Aborting in-progress rebase...", ok_text="Rebase aborted.")
|
|
35
35
|
info("In-progress rebase aborted.")
|
|
36
36
|
except GitCommandError:
|
|
37
37
|
pass
|
|
@@ -76,11 +76,10 @@ def jump_operation(args):
|
|
|
76
76
|
try:
|
|
77
77
|
if has_changes.strip():
|
|
78
78
|
print()
|
|
79
|
-
info("You have unsaved changes
|
|
80
|
-
|
|
81
|
-
if user_input != 'y':
|
|
79
|
+
info("You have unsaved changes in this folder.")
|
|
80
|
+
if not confirm(f"Move your unsaved edits to branch '{target_branch}'? (y/n): "):
|
|
82
81
|
print()
|
|
83
|
-
warning("You cannot switch branches with unsaved
|
|
82
|
+
warning("You cannot switch branches with unsaved edits. Jump canceled.")
|
|
84
83
|
return
|
|
85
84
|
stash_result = git_stash_push(label="GitGo Jump Auto-Stash", loading_msg="Saving your changes before jumping...")
|
|
86
85
|
if not stash_result:
|
|
@@ -93,9 +92,7 @@ def jump_operation(args):
|
|
|
93
92
|
if not is_branch_exist(target_branch):
|
|
94
93
|
print()
|
|
95
94
|
warning(f"Branch '{target_branch}' does not exist.")
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
if user_input != 'y':
|
|
95
|
+
if not confirm(f"Branch '{target_branch}' does not exist yet. Create it and switch to it? (y/n): "):
|
|
99
96
|
info("Exiting without jumping...")
|
|
100
97
|
if stashed_code:
|
|
101
98
|
pop_result = git_stash_pop(loading_msg="Putting your unsaved changes back...")
|
|
@@ -130,12 +127,10 @@ def jump_operation(args):
|
|
|
130
127
|
print()
|
|
131
128
|
error("MERGE CONFLICT — your changes clash with the target branch.")
|
|
132
129
|
print()
|
|
133
|
-
info("Option [Y]: Stay here and fix the conflict lines
|
|
134
|
-
info("Option [N]:
|
|
130
|
+
info("Option [Y]: Stay here and fix the conflict lines in your files.")
|
|
131
|
+
info("Option [N]: Undo the switch and go back to where you started.")
|
|
135
132
|
print()
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
if conflict_choice != 'y':
|
|
133
|
+
if not confirm("Fix the conflicts yourself? (y = stay and fix / n = go back): "):
|
|
139
134
|
undo_jump_operation(original_branch, stashed_code, created_branch)
|
|
140
135
|
return
|
|
141
136
|
else:
|
|
@@ -148,9 +143,10 @@ def jump_operation(args):
|
|
|
148
143
|
drop_result = git_stash_drop(loading_msg="Cleaning up the temporary stash...", ok_text=f"On '{target_branch}'. Your changes came with you.")
|
|
149
144
|
if not drop_result:
|
|
150
145
|
warning("Could not clean up the temporary stash. Run 'gitgo state list' to remove it manually.")
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
146
|
+
|
|
147
|
+
if not getattr(args, 'nested', False):
|
|
148
|
+
banner("WORKSPACE RE-POSITIONED. TARGET DEPLOYMENT SECURED.", "ON TARGET BRANCH WITH RE-APPLIED STATE.")
|
|
149
|
+
return
|
|
154
150
|
|
|
155
151
|
except KeyboardInterrupt:
|
|
156
152
|
print()
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
from pygitgo.commands.git_remote import add_remote_origin, confirm_remote_link
|
|
2
|
-
from pygitgo.utils.
|
|
2
|
+
from pygitgo.utils.cli_io import success, warning, error, info, banner
|
|
3
3
|
from pygitgo.commands.git_core import git_init, git_commit, git_push
|
|
4
4
|
from pygitgo.commands.git_branch import get_current_branch
|
|
5
5
|
from pygitgo.exceptions import GitCommandError, GitGoError
|
|
@@ -23,29 +23,34 @@ def _link_interrupt_cleanup(repo_url, initialized, committed, remote_added):
|
|
|
23
23
|
if committed:
|
|
24
24
|
info("Initial commit was created. Your files are safe.")
|
|
25
25
|
info("Run 'gitgo push' when ready to push to the remote.")
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
26
|
+
return
|
|
27
|
+
|
|
28
|
+
if initialized:
|
|
29
|
+
try:
|
|
30
|
+
import shutil
|
|
31
|
+
import os
|
|
32
|
+
shutil.rmtree(".git")
|
|
33
|
+
success("Local Git repository config removed. Files are untouched.")
|
|
34
|
+
except Exception:
|
|
35
|
+
warning("Could not auto-remove '.git' folder.")
|
|
36
|
+
warning("Run: rmdir /s /q .git (Windows) or rm -rf .git (Mac/Linux)")
|
|
29
37
|
else:
|
|
30
|
-
success("No
|
|
38
|
+
success("No Git state was changed. Your files are safe.")
|
|
31
39
|
|
|
32
40
|
|
|
33
|
-
def link_core(repo_url, commit_message
|
|
41
|
+
def link_core(repo_url, commit_message, silent=False, already_initialized=False):
|
|
34
42
|
if not validate_repo_url(repo_url):
|
|
35
|
-
raise GitGoError(
|
|
36
|
-
"\nInvalid repository URL!\n"
|
|
37
|
-
"Expected format: https://github.com/username/repo.git"
|
|
38
|
-
" or: git@github.com:username/repo.git\n"
|
|
39
|
-
)
|
|
43
|
+
raise GitGoError(f"Invalid remote repository URL: '{repo_url}'")
|
|
40
44
|
|
|
41
45
|
initialized = False
|
|
42
46
|
committed = False
|
|
43
47
|
remote_added = False
|
|
44
48
|
|
|
45
49
|
try:
|
|
50
|
+
main_branch = get_default_branch()
|
|
51
|
+
|
|
46
52
|
if already_initialized:
|
|
47
53
|
is_new_repo = True
|
|
48
|
-
initialized = True
|
|
49
54
|
else:
|
|
50
55
|
is_new_repo = git_init()
|
|
51
56
|
if is_new_repo:
|
|
@@ -55,8 +60,8 @@ def link_core(repo_url, commit_message="Initial commit", silent=False, already_i
|
|
|
55
60
|
add_remote_origin(repo_url)
|
|
56
61
|
remote_added = True
|
|
57
62
|
|
|
58
|
-
|
|
59
|
-
|
|
63
|
+
confirm_remote_link(ok_text="Remote linked to existing repository.")
|
|
64
|
+
info("Ready to push with: gitgo push <branch> 'your message'")
|
|
60
65
|
return
|
|
61
66
|
|
|
62
67
|
commit_made = git_commit(commit_message, loading_msg="Creating initial commit...", ok_text="Initial commit created.")
|
|
@@ -66,18 +71,17 @@ def link_core(repo_url, commit_message="Initial commit", silent=False, already_i
|
|
|
66
71
|
add_remote_origin(repo_url)
|
|
67
72
|
remote_added = True
|
|
68
73
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
main_branch = get_default_branch()
|
|
74
|
+
try:
|
|
75
|
+
current_branch = get_current_branch()
|
|
76
|
+
except GitCommandError as e:
|
|
77
|
+
raise GitGoError(f"Could not determine the current branch: {e}")
|
|
74
78
|
|
|
75
79
|
if current_branch != main_branch:
|
|
76
|
-
run_command(["git", "branch", "-m", main_branch], loading_msg=f"Renaming branch '{current_branch}' to '{main_branch}'...")
|
|
80
|
+
run_command(["git", "branch", "-m", main_branch], loading_msg=f"Renaming branch '{current_branch}' to '{main_branch}'...", ok_text=f"Branch renamed to '{main_branch}'.")
|
|
77
81
|
current_branch = main_branch
|
|
78
82
|
|
|
79
83
|
try:
|
|
80
|
-
remote_refs = run_command(["git", "ls-remote", "--heads", "origin", main_branch], loading_msg="Checking remote branches...")
|
|
84
|
+
remote_refs = run_command(["git", "ls-remote", "--heads", "origin", main_branch], loading_msg="Checking remote branches...", ok_text="Remote branches checked.")
|
|
81
85
|
except GitCommandError:
|
|
82
86
|
remote_refs = None
|
|
83
87
|
|
|
@@ -88,16 +92,16 @@ def link_core(repo_url, commit_message="Initial commit", silent=False, already_i
|
|
|
88
92
|
loading_msg="Pulling and merging remote content...",
|
|
89
93
|
ok_text="Remote content merged."
|
|
90
94
|
)
|
|
91
|
-
except GitCommandError:
|
|
95
|
+
except GitCommandError as e:
|
|
92
96
|
error("Failed to merge remote content. You may need to resolve conflicts manually.")
|
|
93
97
|
warning(f"Run: git pull origin {main_branch} --allow-unrelated-histories")
|
|
94
98
|
warning(f"Then: gitgo push {main_branch} 'your message'\n")
|
|
95
|
-
|
|
99
|
+
raise GitGoError(f"Failed to merge remote content: {e.stderr}" if e.stderr else "Failed to merge remote content.")
|
|
96
100
|
|
|
97
101
|
git_push(current_branch)
|
|
98
102
|
|
|
99
103
|
if not silent:
|
|
100
|
-
|
|
104
|
+
banner("REPOSITORY INITIALIZED AND DEPLOYED.", "LOCAL REPOSITORY CONNECTED TO REMOTE ORIGIN.")
|
|
101
105
|
print()
|
|
102
106
|
info("Run 'gitgo undo link' to remove the remote and undo the initial commit.")
|
|
103
107
|
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
from pygitgo.utils.cli_io import info, error, warning, confirm, success, banner
|
|
2
|
+
from pygitgo.commands.init import init_operation
|
|
3
|
+
from pygitgo.commands.repo import repo_operation
|
|
4
|
+
from pygitgo.utils.platform import get_platform
|
|
5
|
+
from pygitgo.commands.link import link_core
|
|
6
|
+
from pygitgo.exceptions import GitGoError
|
|
7
|
+
import sys
|
|
8
|
+
import os
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def _assert_not_inside_target(repo_name):
|
|
12
|
+
# This will abort operation if the user is already inside the folder with same name as repo
|
|
13
|
+
|
|
14
|
+
cwd_basename = os.path.basename(os.path.abspath("."))
|
|
15
|
+
|
|
16
|
+
if get_platform() == "windows":
|
|
17
|
+
match = cwd_basename.lower() == repo_name.lower()
|
|
18
|
+
else:
|
|
19
|
+
match = cwd_basename == repo_name
|
|
20
|
+
|
|
21
|
+
if match:
|
|
22
|
+
raise GitGoError(
|
|
23
|
+
f"\nDirectory mismatch detected.\n\n"
|
|
24
|
+
f" You are already inside '{repo_name}/', but you ran: gitgo new {repo_name}\n\n"
|
|
25
|
+
f" 'gitgo new' creates a NEW folder from scratch. If you want to:\n\n"
|
|
26
|
+
f" → Publish this existing folder to GitHub, run:\n"
|
|
27
|
+
f" gitgo repo (creates the GitHub repo)\n"
|
|
28
|
+
f" gitgo link <repo-url> (links and pushes)\n\n"
|
|
29
|
+
f" → Start completely fresh in a new folder, cd out first:\n"
|
|
30
|
+
f" cd ..\n"
|
|
31
|
+
f" gitgo new {repo_name}\n"
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def new_operation(args):
|
|
36
|
+
|
|
37
|
+
_assert_not_inside_target(args.name)
|
|
38
|
+
|
|
39
|
+
init_operation(args)
|
|
40
|
+
|
|
41
|
+
os.chdir(args.name)
|
|
42
|
+
|
|
43
|
+
repo_url = repo_operation(args, silent=True)
|
|
44
|
+
|
|
45
|
+
try:
|
|
46
|
+
link_core(repo_url, "Initial commit", silent=True, already_initialized=True)
|
|
47
|
+
except GitGoError as e:
|
|
48
|
+
error(str(e))
|
|
49
|
+
from pygitgo.commands.repo import delete_github_repo, parse_repo_fullname
|
|
50
|
+
warning(f"An orphaned remote repository was created on GitHub: {repo_url}")
|
|
51
|
+
info("It needs manual deletion or a retry of 'gitgo link'.")
|
|
52
|
+
full_name = parse_repo_fullname(repo_url)
|
|
53
|
+
if full_name:
|
|
54
|
+
if confirm("Delete the repo I just created on GitHub? (y/n): ", destructive=True):
|
|
55
|
+
try:
|
|
56
|
+
delete_github_repo(full_name)
|
|
57
|
+
success("GitHub repository deleted successfully.")
|
|
58
|
+
except Exception as delete_err:
|
|
59
|
+
error(f"Failed to delete: {delete_err}")
|
|
60
|
+
sys.exit(1)
|
|
61
|
+
|
|
62
|
+
banner("PROJECT LAUNCHED. SCAFFOLDED, CREATED, AND DEPLOYED.", "LOCAL STRUCTURE ESTABLISHED AND REMOTE SYNCED.")
|
|
63
|
+
|
|
64
|
+
print()
|
|
65
|
+
info("Run 'gitgo undo link' to remove the remote and undo the initial commit.")
|
|
66
|
+
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
+
from pygitgo.utils.cli_io import success, warning, error, info
|
|
1
2
|
from pygitgo.commands.git_branch import get_current_branch
|
|
2
|
-
from pygitgo.utils.colors import success, warning, error, info
|
|
3
3
|
from pygitgo.exceptions import GitCommandError, GitGoError
|
|
4
4
|
from pygitgo.utils.executor import run_command
|
|
5
5
|
from pathlib import Path
|
|
@@ -40,7 +40,12 @@ def pull_operation(args):
|
|
|
40
40
|
|
|
41
41
|
try:
|
|
42
42
|
try:
|
|
43
|
-
run_command(
|
|
43
|
+
run_command(
|
|
44
|
+
["git", "ls-remote", "--heads", "origin", branch],
|
|
45
|
+
loading_msg=f"Checking if '{branch}' exists on remote...",
|
|
46
|
+
ok_text=f"Branch '{branch}' found on remote.",
|
|
47
|
+
err_text=f"Branch '{branch}' does not exist on the remote."
|
|
48
|
+
)
|
|
44
49
|
except GitCommandError:
|
|
45
50
|
error(f"Branch '{branch}' does not exist on the remote.")
|
|
46
51
|
info("Push your local branch first, or verify the branch name.")
|
|
@@ -52,6 +57,9 @@ def pull_operation(args):
|
|
|
52
57
|
ok_text=f"Project is up to date with '{branch}'."
|
|
53
58
|
)
|
|
54
59
|
|
|
60
|
+
from pygitgo.utils.cli_io import banner
|
|
61
|
+
banner("REMOTE SYNCHRONIZED. LATEST CHANGES ACQUIRED.", "LOCAL WORKSPACE UPDATED AND ALIGNED.")
|
|
62
|
+
|
|
55
63
|
except KeyboardInterrupt:
|
|
56
64
|
print()
|
|
57
65
|
warning("Pull interrupted (Ctrl+C).")
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
from pygitgo.commands.staging import get_changed_files, display_file_picker, selective_stage
|
|
2
2
|
from pygitgo.commands.git_branch import git_new_branch, get_current_branch, is_branch_exist
|
|
3
|
-
from pygitgo.utils.
|
|
3
|
+
from pygitgo.utils.cli_io import info, warning, success, confirm, banner
|
|
4
4
|
from pygitgo.commands.git_core import git_commit, git_push
|
|
5
5
|
from pygitgo.exceptions import GitCommandError, GitGoError
|
|
6
6
|
from pygitgo.commands.jump import jump_operation
|
|
@@ -87,9 +87,12 @@ def push_operation(args):
|
|
|
87
87
|
elif branch and is_branch_exist(branch):
|
|
88
88
|
current_branch = get_current_branch()
|
|
89
89
|
if current_branch != branch:
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
90
|
+
if confirm(f"Branch '{branch}' already exists. Switch to it before pushing? (y/n): "):
|
|
91
|
+
info(f"Switching to target branch '{branch}'...")
|
|
92
|
+
jump_operation(Namespace(branch=branch, nested=True))
|
|
93
|
+
auto_switched_from = current_branch
|
|
94
|
+
else:
|
|
95
|
+
raise GitGoError("Push aborted.")
|
|
93
96
|
|
|
94
97
|
elif not branch:
|
|
95
98
|
branch = get_current_branch()
|
|
@@ -111,7 +114,7 @@ def push_operation(args):
|
|
|
111
114
|
return
|
|
112
115
|
|
|
113
116
|
selective_stage(selected)
|
|
114
|
-
commit_made = git_commit(message, loading_msg="
|
|
117
|
+
commit_made = git_commit(message, loading_msg="Committing selected files...", skip_staging=True)
|
|
115
118
|
|
|
116
119
|
if commit_made:
|
|
117
120
|
git_push(branch)
|
|
@@ -139,7 +142,7 @@ def push_operation(args):
|
|
|
139
142
|
warning("Make some changes first or check your git remote configuration.")
|
|
140
143
|
return
|
|
141
144
|
|
|
142
|
-
|
|
145
|
+
banner("MISSION COMPLETE. ALL TARGETS COMMITTED AND PUSHED.", "REMOTE TARGETS ALIGNED WITH LOCAL EDITS.")
|
|
143
146
|
|
|
144
147
|
print()
|
|
145
148
|
if auto_switched_from:
|