gitpush-tool 0.2.0__tar.gz → 0.2.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.
- {gitpush_tool-0.2.0/gitpush_tool.egg-info → gitpush_tool-0.2.2}/PKG-INFO +1 -1
- gitpush_tool-0.2.2/gitpush_tool/__init__.py +1 -0
- gitpush_tool-0.2.2/gitpush_tool/cli.py +241 -0
- {gitpush_tool-0.2.0 → gitpush_tool-0.2.2/gitpush_tool.egg-info}/PKG-INFO +1 -1
- {gitpush_tool-0.2.0 → gitpush_tool-0.2.2}/setup.py +1 -1
- gitpush_tool-0.2.0/gitpush_tool/__init__.py +0 -1
- gitpush_tool-0.2.0/gitpush_tool/cli.py +0 -285
- {gitpush_tool-0.2.0 → gitpush_tool-0.2.2}/LICENSE +0 -0
- {gitpush_tool-0.2.0 → gitpush_tool-0.2.2}/MANIFEST.in +0 -0
- {gitpush_tool-0.2.0 → gitpush_tool-0.2.2}/README.md +0 -0
- {gitpush_tool-0.2.0 → gitpush_tool-0.2.2}/gitpush_tool.egg-info/SOURCES.txt +0 -0
- {gitpush_tool-0.2.0 → gitpush_tool-0.2.2}/gitpush_tool.egg-info/dependency_links.txt +0 -0
- {gitpush_tool-0.2.0 → gitpush_tool-0.2.2}/gitpush_tool.egg-info/entry_points.txt +0 -0
- {gitpush_tool-0.2.0 → gitpush_tool-0.2.2}/gitpush_tool.egg-info/requires.txt +0 -0
- {gitpush_tool-0.2.0 → gitpush_tool-0.2.2}/gitpush_tool.egg-info/top_level.txt +0 -0
- {gitpush_tool-0.2.0 → gitpush_tool-0.2.2}/pyproject.toml +0 -0
- {gitpush_tool-0.2.0 → gitpush_tool-0.2.2}/setup.cfg +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.2.2"
|
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
import os
|
|
3
|
+
import argparse
|
|
4
|
+
import sys
|
|
5
|
+
import subprocess
|
|
6
|
+
from datetime import datetime
|
|
7
|
+
import requests
|
|
8
|
+
|
|
9
|
+
def check_gh_installed():
|
|
10
|
+
"""Check if GitHub CLI is installed"""
|
|
11
|
+
try:
|
|
12
|
+
subprocess.run(["gh", "--version"], check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
|
13
|
+
return True
|
|
14
|
+
except:
|
|
15
|
+
return False
|
|
16
|
+
|
|
17
|
+
def gh_authenticated():
|
|
18
|
+
"""Check if user is authenticated with GitHub CLI"""
|
|
19
|
+
try:
|
|
20
|
+
result = subprocess.run(["gh", "auth", "status"], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
|
21
|
+
return result.returncode == 0
|
|
22
|
+
except:
|
|
23
|
+
return False
|
|
24
|
+
|
|
25
|
+
def authenticate_with_gh():
|
|
26
|
+
"""Authenticate user with GitHub CLI"""
|
|
27
|
+
print("\n🔑 GitHub authentication required")
|
|
28
|
+
print("We'll use the GitHub CLI (gh) for authentication")
|
|
29
|
+
print("This will open your browser for secure login")
|
|
30
|
+
|
|
31
|
+
try:
|
|
32
|
+
subprocess.run(["gh", "auth", "login", "--web", "-h", "github.com"], check=True)
|
|
33
|
+
return True
|
|
34
|
+
except subprocess.CalledProcessError:
|
|
35
|
+
print("❌ Authentication failed")
|
|
36
|
+
return False
|
|
37
|
+
except FileNotFoundError:
|
|
38
|
+
print("❌ GitHub CLI not found")
|
|
39
|
+
return False
|
|
40
|
+
|
|
41
|
+
def initialize_git_repository():
|
|
42
|
+
"""Initialize git repository if not already initialized"""
|
|
43
|
+
if not os.path.exists(".git"):
|
|
44
|
+
print("🛠 Initializing git repository")
|
|
45
|
+
subprocess.run(["git", "init"], check=True)
|
|
46
|
+
subprocess.run(["git", "branch", "-M", "main"], check=True)
|
|
47
|
+
|
|
48
|
+
# Create basic .gitignore if doesn't exist
|
|
49
|
+
if not os.path.exists(".gitignore"):
|
|
50
|
+
with open(".gitignore", "w") as f:
|
|
51
|
+
f.write("""# Python
|
|
52
|
+
__pycache__/
|
|
53
|
+
*.py[cod]
|
|
54
|
+
*.so
|
|
55
|
+
.Python
|
|
56
|
+
env/
|
|
57
|
+
venv/
|
|
58
|
+
.env
|
|
59
|
+
|
|
60
|
+
# IDE
|
|
61
|
+
.vscode/
|
|
62
|
+
.idea/
|
|
63
|
+
*.swp
|
|
64
|
+
*.swo
|
|
65
|
+
|
|
66
|
+
# System
|
|
67
|
+
.DS_Store
|
|
68
|
+
Thumbs.db
|
|
69
|
+
|
|
70
|
+
# Project specific
|
|
71
|
+
*.log
|
|
72
|
+
*.tmp
|
|
73
|
+
*.bak
|
|
74
|
+
""")
|
|
75
|
+
print("📁 Created .gitignore file")
|
|
76
|
+
return True
|
|
77
|
+
return False
|
|
78
|
+
|
|
79
|
+
def create_initial_commit(commit_message="Initial commit"):
|
|
80
|
+
"""Create initial commit if no commits exist"""
|
|
81
|
+
try:
|
|
82
|
+
# Check if there are any commits
|
|
83
|
+
result = subprocess.run(["git", "rev-list", "--count", "HEAD"],
|
|
84
|
+
stdout=subprocess.PIPE,
|
|
85
|
+
stderr=subprocess.PIPE,
|
|
86
|
+
text=True)
|
|
87
|
+
commit_count = int(result.stdout.strip()) if result.stdout.strip().isdigit() else 0
|
|
88
|
+
|
|
89
|
+
if commit_count == 0:
|
|
90
|
+
print("📦 Creating initial commit")
|
|
91
|
+
subprocess.run(["git", "add", "."], check=True)
|
|
92
|
+
subprocess.run(["git", "commit", "-m", commit_message], check=True)
|
|
93
|
+
return True
|
|
94
|
+
return False
|
|
95
|
+
except subprocess.CalledProcessError:
|
|
96
|
+
return False
|
|
97
|
+
|
|
98
|
+
def create_with_gh_cli(repo_name, private=False, description="", commit_message="Initial commit"):
|
|
99
|
+
"""Create and push to new repository using GitHub CLI"""
|
|
100
|
+
try:
|
|
101
|
+
private_flag = "--private" if private else "--public"
|
|
102
|
+
cmd = [
|
|
103
|
+
"gh", "repo", "create", repo_name,
|
|
104
|
+
private_flag,
|
|
105
|
+
"--source=.",
|
|
106
|
+
"--remote=origin",
|
|
107
|
+
"--push"
|
|
108
|
+
]
|
|
109
|
+
|
|
110
|
+
if description:
|
|
111
|
+
cmd.extend(["--description", description])
|
|
112
|
+
|
|
113
|
+
# Initialize Git and create initial commit if needed
|
|
114
|
+
needs_init = initialize_git_repository()
|
|
115
|
+
needs_commit = create_initial_commit(commit_message)
|
|
116
|
+
|
|
117
|
+
if needs_init or needs_commit:
|
|
118
|
+
print("⚡ Set up local Git repository with initial commit")
|
|
119
|
+
|
|
120
|
+
# Run the create command
|
|
121
|
+
result = subprocess.run(cmd, check=True)
|
|
122
|
+
|
|
123
|
+
if result.returncode == 0:
|
|
124
|
+
# Get the repo URL
|
|
125
|
+
url_result = subprocess.run(
|
|
126
|
+
["gh", "repo", "view", "--json", "url", "--jq", ".url"],
|
|
127
|
+
stdout=subprocess.PIPE,
|
|
128
|
+
text=True,
|
|
129
|
+
check=True
|
|
130
|
+
)
|
|
131
|
+
repo_url = url_result.stdout.strip()
|
|
132
|
+
print(f"✅ Successfully created repository: {repo_url}")
|
|
133
|
+
return True
|
|
134
|
+
return False
|
|
135
|
+
except subprocess.CalledProcessError as e:
|
|
136
|
+
print(f"❌ Failed to create repository: {e.stderr if e.stderr else 'Unknown error'}")
|
|
137
|
+
return False
|
|
138
|
+
|
|
139
|
+
def check_for_updates():
|
|
140
|
+
"""Check for newer versions on PyPI"""
|
|
141
|
+
try:
|
|
142
|
+
current_version = "0.2.2"
|
|
143
|
+
response = requests.get("https://pypi.org/pypi/gitpush-tool/json", timeout=2)
|
|
144
|
+
latest_version = response.json()["info"]["version"]
|
|
145
|
+
if latest_version != current_version:
|
|
146
|
+
print(f"ℹ️ New version available: {latest_version} (you have {current_version})")
|
|
147
|
+
print(" Run 'pip install --upgrade gitpush-tool' to update")
|
|
148
|
+
except:
|
|
149
|
+
pass
|
|
150
|
+
|
|
151
|
+
def run():
|
|
152
|
+
parser = argparse.ArgumentParser(
|
|
153
|
+
description="🚀 Supercharged Git push tool with GitHub repo creation",
|
|
154
|
+
formatter_class=argparse.RawDescriptionHelpFormatter,
|
|
155
|
+
epilog="""Examples:
|
|
156
|
+
Basic push: gitpush_tool "Commit message"
|
|
157
|
+
Create new repo: gitpush_tool "Initial commit" --new-repo project-name
|
|
158
|
+
Private repository: gitpush_tool --new-repo private-project --private
|
|
159
|
+
Force push: gitpush_tool "Fix critical bug" --force
|
|
160
|
+
Push specific branch: gitpush_tool "Update feature" feature-branch upstream
|
|
161
|
+
"""
|
|
162
|
+
)
|
|
163
|
+
parser.add_argument("commit", nargs="?", help="Commit message")
|
|
164
|
+
parser.add_argument("branch", nargs="?", default="main", help="Branch name (default: main)")
|
|
165
|
+
parser.add_argument("remote", nargs="?", default="origin", help="Remote name (default: origin)")
|
|
166
|
+
parser.add_argument("--force", action="store_true", help="Force push with --force-with-lease")
|
|
167
|
+
parser.add_argument("--tags", action="store_true", help="Push tags")
|
|
168
|
+
parser.add_argument("--init", action="store_true", help="Initialize git repo")
|
|
169
|
+
parser.add_argument("--new-repo", metavar="NAME", help="Create new GitHub repository")
|
|
170
|
+
parser.add_argument("--private", action="store_true", help="Make repository private")
|
|
171
|
+
parser.add_argument("--description", help="Repository description")
|
|
172
|
+
|
|
173
|
+
args = parser.parse_args()
|
|
174
|
+
|
|
175
|
+
if args.new_repo:
|
|
176
|
+
print(f"🆕 Creating repository: {args.new_repo}")
|
|
177
|
+
|
|
178
|
+
# Check if GitHub CLI is installed
|
|
179
|
+
if not check_gh_installed():
|
|
180
|
+
print("❌ GitHub CLI (gh) is not installed")
|
|
181
|
+
print("Please install it first:")
|
|
182
|
+
print(" Mac (Homebrew): brew install gh")
|
|
183
|
+
print(" Windows (Winget): winget install --id GitHub.cli")
|
|
184
|
+
print(" Linux: See https://github.com/cli/cli#installation")
|
|
185
|
+
sys.exit(1)
|
|
186
|
+
|
|
187
|
+
# Check if authenticated
|
|
188
|
+
if not gh_authenticated():
|
|
189
|
+
if not authenticate_with_gh():
|
|
190
|
+
sys.exit(1)
|
|
191
|
+
|
|
192
|
+
# Create repository with automatic initialization
|
|
193
|
+
commit_msg = args.commit if args.commit else "Initial commit"
|
|
194
|
+
if not create_with_gh_cli(
|
|
195
|
+
args.new_repo,
|
|
196
|
+
private=args.private,
|
|
197
|
+
description=args.description or "",
|
|
198
|
+
commit_message=commit_msg
|
|
199
|
+
):
|
|
200
|
+
sys.exit(1)
|
|
201
|
+
|
|
202
|
+
# Exit after creating new repo unless there are other operations
|
|
203
|
+
if not args.commit and not args.force and not args.tags:
|
|
204
|
+
sys.exit(0)
|
|
205
|
+
|
|
206
|
+
if args.init:
|
|
207
|
+
if initialize_git_repository():
|
|
208
|
+
create_initial_commit(args.commit or "Initial commit")
|
|
209
|
+
|
|
210
|
+
# Stage all changes if not in a new repo creation
|
|
211
|
+
if not args.new_repo:
|
|
212
|
+
subprocess.run(["git", "add", "."], check=True)
|
|
213
|
+
|
|
214
|
+
if args.commit:
|
|
215
|
+
print(f"📦 Committing: '{args.commit}'")
|
|
216
|
+
try:
|
|
217
|
+
subprocess.run(['git', 'commit', '-m', args.commit], check=True)
|
|
218
|
+
except subprocess.CalledProcessError:
|
|
219
|
+
print("❌ Commit failed - no changes to commit?")
|
|
220
|
+
sys.exit(1)
|
|
221
|
+
|
|
222
|
+
# Build push command
|
|
223
|
+
push_cmd = ["git", "push"]
|
|
224
|
+
if args.force:
|
|
225
|
+
push_cmd.append("--force-with-lease")
|
|
226
|
+
if args.tags:
|
|
227
|
+
push_cmd.append("--tags")
|
|
228
|
+
if args.remote and args.branch:
|
|
229
|
+
push_cmd.extend([args.remote, args.branch])
|
|
230
|
+
|
|
231
|
+
print(f"🚀 Executing: {' '.join(push_cmd)}")
|
|
232
|
+
try:
|
|
233
|
+
subprocess.run(push_cmd, check=True)
|
|
234
|
+
print("✅ Successfully pushed changes")
|
|
235
|
+
except subprocess.CalledProcessError:
|
|
236
|
+
print("❌ Push failed")
|
|
237
|
+
sys.exit(1)
|
|
238
|
+
|
|
239
|
+
if __name__ == "__main__":
|
|
240
|
+
check_for_updates()
|
|
241
|
+
run()
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "0.2.0"
|
|
@@ -1,285 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
import os
|
|
3
|
-
import argparse
|
|
4
|
-
import sys
|
|
5
|
-
import requests
|
|
6
|
-
from getpass import getpass
|
|
7
|
-
import json
|
|
8
|
-
from datetime import datetime
|
|
9
|
-
|
|
10
|
-
def get_github_token():
|
|
11
|
-
"""Get GitHub token from various sources with priority order"""
|
|
12
|
-
# 1. Check environment variable
|
|
13
|
-
token = os.getenv("GITHUB_TOKEN")
|
|
14
|
-
|
|
15
|
-
# 2. Check token file
|
|
16
|
-
if not token:
|
|
17
|
-
token_path = os.path.join(os.path.dirname(__file__), '..', 'token')
|
|
18
|
-
if os.path.exists(token_path):
|
|
19
|
-
with open(token_path, 'r') as f:
|
|
20
|
-
token = f.read().strip()
|
|
21
|
-
|
|
22
|
-
# 3. Prompt user if still not found
|
|
23
|
-
if not token:
|
|
24
|
-
print("\n🔑 GitHub personal access token is required to create repositories.")
|
|
25
|
-
print("Create one at: https://github.com/settings/tokens (with 'repo' scope)")
|
|
26
|
-
token = getpass("Enter your GitHub token: ")
|
|
27
|
-
|
|
28
|
-
return token
|
|
29
|
-
|
|
30
|
-
def get_github_username():
|
|
31
|
-
"""Get GitHub username from config or API"""
|
|
32
|
-
try:
|
|
33
|
-
# Try git config first
|
|
34
|
-
username = os.popen("git config github.user").read().strip()
|
|
35
|
-
if username:
|
|
36
|
-
return username
|
|
37
|
-
|
|
38
|
-
# Fallback to API if token exists
|
|
39
|
-
token = get_github_token()
|
|
40
|
-
if token:
|
|
41
|
-
headers = {
|
|
42
|
-
"Authorization": f"token {token}",
|
|
43
|
-
"Accept": "application/vnd.github+json"
|
|
44
|
-
}
|
|
45
|
-
response = requests.get("https://api.github.com/user", headers=headers)
|
|
46
|
-
if response.status_code == 200:
|
|
47
|
-
return response.json().get("login")
|
|
48
|
-
except:
|
|
49
|
-
pass
|
|
50
|
-
return None
|
|
51
|
-
|
|
52
|
-
def create_github_repo(repo_name, private=False, description=""):
|
|
53
|
-
"""Create a new GitHub repository using the GitHub API"""
|
|
54
|
-
token = get_github_token()
|
|
55
|
-
|
|
56
|
-
if not token:
|
|
57
|
-
print("❌ GitHub token is required to create a repository")
|
|
58
|
-
return None
|
|
59
|
-
|
|
60
|
-
headers = {
|
|
61
|
-
"Authorization": f"token {token}",
|
|
62
|
-
"Accept": "application/vnd.github+json",
|
|
63
|
-
"X-GitHub-Api-Version": "2022-11-28"
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
data = {
|
|
67
|
-
"name": repo_name,
|
|
68
|
-
"description": description,
|
|
69
|
-
"private": private,
|
|
70
|
-
"auto_init": False,
|
|
71
|
-
"has_issues": True,
|
|
72
|
-
"has_projects": False,
|
|
73
|
-
"has_wiki": False
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
try:
|
|
77
|
-
response = requests.post(
|
|
78
|
-
"https://api.github.com/user/repos",
|
|
79
|
-
headers=headers,
|
|
80
|
-
json=data,
|
|
81
|
-
timeout=10
|
|
82
|
-
)
|
|
83
|
-
|
|
84
|
-
# Detailed error handling
|
|
85
|
-
if response.status_code == 401:
|
|
86
|
-
print("❌ Authentication failed. Invalid or expired token.")
|
|
87
|
-
print("Please create a new token with 'repo' scope at:")
|
|
88
|
-
print("https://github.com/settings/tokens")
|
|
89
|
-
return None
|
|
90
|
-
|
|
91
|
-
elif response.status_code == 403:
|
|
92
|
-
print("❌ Permission denied (403 Forbidden). Possible reasons:")
|
|
93
|
-
print("- Token doesn't have 'repo' scope")
|
|
94
|
-
print("- Token is restricted to specific repositories")
|
|
95
|
-
print("- GitHub API rate limit exceeded")
|
|
96
|
-
|
|
97
|
-
# Try to get rate limit info
|
|
98
|
-
try:
|
|
99
|
-
limits = requests.get(
|
|
100
|
-
"https://api.github.com/rate_limit",
|
|
101
|
-
headers=headers
|
|
102
|
-
).json()
|
|
103
|
-
remaining = limits['resources']['core']['remaining']
|
|
104
|
-
reset_time = datetime.fromtimestamp(limits['resources']['core']['reset']).strftime('%Y-%m-%d %H:%M:%S')
|
|
105
|
-
print(f"⏳ API calls remaining: {remaining}")
|
|
106
|
-
print(f"🔄 Rate limit resets at: {reset_time}")
|
|
107
|
-
except:
|
|
108
|
-
pass
|
|
109
|
-
|
|
110
|
-
return None
|
|
111
|
-
|
|
112
|
-
elif response.status_code == 422:
|
|
113
|
-
error_data = response.json()
|
|
114
|
-
if 'errors' in error_data:
|
|
115
|
-
for error in error_data['errors']:
|
|
116
|
-
if error.get('field') == 'name' and 'already exists' in error.get('message', ''):
|
|
117
|
-
print(f"❌ Repository '{repo_name}' already exists")
|
|
118
|
-
return None
|
|
119
|
-
print(f"❌ Validation error: {error_data.get('message', 'Unknown error')}")
|
|
120
|
-
return None
|
|
121
|
-
|
|
122
|
-
elif response.status_code != 201:
|
|
123
|
-
print(f"❌ Failed to create repository (HTTP {response.status_code}): {response.text}")
|
|
124
|
-
return None
|
|
125
|
-
|
|
126
|
-
repo_url = response.json()["html_url"]
|
|
127
|
-
print(f"✅ Successfully created repository: {repo_url}")
|
|
128
|
-
return repo_url
|
|
129
|
-
|
|
130
|
-
except requests.exceptions.RequestException as e:
|
|
131
|
-
print(f"❌ Failed to create repository: {str(e)}")
|
|
132
|
-
if "Max retries exceeded" in str(e):
|
|
133
|
-
print("⚠️ Network connection problem detected")
|
|
134
|
-
return None
|
|
135
|
-
|
|
136
|
-
def create_with_gh_cli(repo_name, private=False, description=""):
|
|
137
|
-
"""Alternative using GitHub CLI if installed"""
|
|
138
|
-
try:
|
|
139
|
-
private_flag = "--private" if private else "--public"
|
|
140
|
-
cmd = f"gh repo create {repo_name} {private_flag} --source=. --remote=origin --push"
|
|
141
|
-
if description:
|
|
142
|
-
cmd += f" --description \"{description}\""
|
|
143
|
-
return os.system(cmd) == 0
|
|
144
|
-
except:
|
|
145
|
-
return False
|
|
146
|
-
|
|
147
|
-
def initialize_repository(remote_url=None):
|
|
148
|
-
"""Initialize git repository with sensible defaults"""
|
|
149
|
-
if not os.path.exists(".git"):
|
|
150
|
-
print("🛠 Initializing git repository")
|
|
151
|
-
os.system("git init")
|
|
152
|
-
os.system("git branch -M main")
|
|
153
|
-
|
|
154
|
-
if remote_url:
|
|
155
|
-
os.system(f"git remote add origin {remote_url}")
|
|
156
|
-
|
|
157
|
-
# Create basic .gitignore if doesn't exist
|
|
158
|
-
if not os.path.exists(".gitignore"):
|
|
159
|
-
with open(".gitignore", "w") as f:
|
|
160
|
-
f.write("""# Python
|
|
161
|
-
__pycache__/
|
|
162
|
-
*.py[cod]
|
|
163
|
-
*.so
|
|
164
|
-
.Python
|
|
165
|
-
env/
|
|
166
|
-
venv/
|
|
167
|
-
.env
|
|
168
|
-
|
|
169
|
-
# IDE
|
|
170
|
-
.vscode/
|
|
171
|
-
.idea/
|
|
172
|
-
*.swp
|
|
173
|
-
*.swo
|
|
174
|
-
|
|
175
|
-
# System
|
|
176
|
-
.DS_Store
|
|
177
|
-
Thumbs.db
|
|
178
|
-
|
|
179
|
-
# Project specific
|
|
180
|
-
*.log
|
|
181
|
-
*.tmp
|
|
182
|
-
*.bak
|
|
183
|
-
""")
|
|
184
|
-
print("📁 Created .gitignore file")
|
|
185
|
-
|
|
186
|
-
def check_for_updates():
|
|
187
|
-
"""Check for newer versions on PyPI"""
|
|
188
|
-
try:
|
|
189
|
-
current_version = "0.2.0" # Should match your setup.py
|
|
190
|
-
response = requests.get("https://pypi.org/pypi/gitpush-tool/json", timeout=2)
|
|
191
|
-
latest_version = response.json()["info"]["version"]
|
|
192
|
-
if latest_version != current_version:
|
|
193
|
-
print(f"ℹ️ New version available: {latest_version} (you have {current_version})")
|
|
194
|
-
print(" Run 'pip install --upgrade gitpush-tool' to update")
|
|
195
|
-
except:
|
|
196
|
-
pass
|
|
197
|
-
|
|
198
|
-
def run():
|
|
199
|
-
parser = argparse.ArgumentParser(
|
|
200
|
-
description="🚀 Supercharged Git push tool with GitHub repo creation",
|
|
201
|
-
formatter_class=argparse.RawDescriptionHelpFormatter,
|
|
202
|
-
epilog="""Examples:
|
|
203
|
-
Basic push: gitpush_tool "Commit message"
|
|
204
|
-
Create new repo: gitpush_tool "Initial commit" --new-repo project-name
|
|
205
|
-
Private repository: gitpush_tool --new-repo private-project --private
|
|
206
|
-
Force push: gitpush_tool "Fix critical bug" --force
|
|
207
|
-
Push specific branch: gitpush_tool "Update feature" feature-branch upstream
|
|
208
|
-
"""
|
|
209
|
-
)
|
|
210
|
-
parser.add_argument("commit", nargs="?", help="Commit message")
|
|
211
|
-
parser.add_argument("branch", nargs="?", default="main", help="Branch name (default: main)")
|
|
212
|
-
parser.add_argument("remote", nargs="?", default="origin", help="Remote name (default: origin)")
|
|
213
|
-
parser.add_argument("--force", action="store_true", help="Force push with --force-with-lease")
|
|
214
|
-
parser.add_argument("--tags", action="store_true", help="Push tags")
|
|
215
|
-
parser.add_argument("--init", action="store_true", help="Initialize git repo")
|
|
216
|
-
parser.add_argument("--new-repo", metavar="NAME", help="Create new GitHub repository")
|
|
217
|
-
parser.add_argument("--private", action="store_true", help="Make repository private")
|
|
218
|
-
parser.add_argument("--description", help="Repository description")
|
|
219
|
-
|
|
220
|
-
args = parser.parse_args()
|
|
221
|
-
|
|
222
|
-
if args.new_repo:
|
|
223
|
-
print(f"🆕 Creating repository: {args.new_repo}")
|
|
224
|
-
repo_url = create_github_repo(
|
|
225
|
-
args.new_repo,
|
|
226
|
-
private=args.private,
|
|
227
|
-
description=args.description or ""
|
|
228
|
-
)
|
|
229
|
-
|
|
230
|
-
# Fallback to GitHub CLI if API fails
|
|
231
|
-
if not repo_url:
|
|
232
|
-
print("⚠️ Falling back to GitHub CLI...")
|
|
233
|
-
if create_with_gh_cli(args.new_repo, args.private, args.description):
|
|
234
|
-
username = get_github_username()
|
|
235
|
-
if username:
|
|
236
|
-
repo_url = f"https://github.com/{username}/{args.new_repo}.git"
|
|
237
|
-
else:
|
|
238
|
-
repo_url = None
|
|
239
|
-
else:
|
|
240
|
-
print("❌ Could not create repository. Please check your credentials.")
|
|
241
|
-
print("You can install GitHub CLI with: brew install gh (Mac) or winget install --id GitHub.cli (Windows)")
|
|
242
|
-
sys.exit(1)
|
|
243
|
-
|
|
244
|
-
if repo_url:
|
|
245
|
-
initialize_repository(repo_url)
|
|
246
|
-
args.init = False # Already initialized
|
|
247
|
-
else:
|
|
248
|
-
sys.exit(1)
|
|
249
|
-
|
|
250
|
-
if args.init:
|
|
251
|
-
initialize_repository()
|
|
252
|
-
|
|
253
|
-
# Stage all changes
|
|
254
|
-
os.system("git add .")
|
|
255
|
-
|
|
256
|
-
if args.commit:
|
|
257
|
-
print(f"📦 Committing: '{args.commit}'")
|
|
258
|
-
commit_result = os.system(f'git commit -m "{args.commit}"')
|
|
259
|
-
if commit_result != 0:
|
|
260
|
-
print("❌ Commit failed")
|
|
261
|
-
sys.exit(1)
|
|
262
|
-
else:
|
|
263
|
-
print("⚠️ Skipping commit (no message provided)")
|
|
264
|
-
|
|
265
|
-
# Build push command
|
|
266
|
-
push_cmd = "git push"
|
|
267
|
-
if args.force:
|
|
268
|
-
push_cmd += " --force-with-lease"
|
|
269
|
-
if args.tags:
|
|
270
|
-
push_cmd += " --tags"
|
|
271
|
-
if args.remote and args.branch:
|
|
272
|
-
push_cmd += f" {args.remote} {args.branch}"
|
|
273
|
-
|
|
274
|
-
print(f"🚀 Executing: {push_cmd}")
|
|
275
|
-
push_result = os.system(push_cmd)
|
|
276
|
-
|
|
277
|
-
if push_result == 0:
|
|
278
|
-
print("✅ Successfully pushed changes")
|
|
279
|
-
else:
|
|
280
|
-
print("❌ Push failed")
|
|
281
|
-
sys.exit(1)
|
|
282
|
-
|
|
283
|
-
if __name__ == "__main__":
|
|
284
|
-
check_for_updates()
|
|
285
|
-
run()
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|