Skip to content

Commit c511499

Browse files
working code for gh-fork-sync
0 parents  commit c511499

File tree

7 files changed

+154
-0
lines changed

7 files changed

+154
-0
lines changed

.github/workflows/python-app.yml

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
name: Python application
2+
3+
on:
4+
push:
5+
branches: [ main ]
6+
pull_request:
7+
branches: [ main ]
8+
9+
jobs:
10+
build:
11+
runs-on: ubuntu-latest
12+
13+
steps:
14+
- uses: actions/checkout@v3
15+
- name: Set up Python
16+
uses: actions/setup-python@v4
17+
with:
18+
python-version: '3.x'
19+
20+
- name: Install dependencies
21+
run: |
22+
python -m pip install --upgrade pip
23+
pip install -r requirements.txt
24+
25+
- name: Lint with flake8
26+
run: |
27+
pip install flake8
28+
flake8 gh_fork_sync.py

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
__pycache__/
2+
*.pyc
3+
.env

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2025 Shripad Bankar
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# 🔄 GitHub Fork Sync
2+
3+
[![Python](https://img.shields.io/badge/Python-3.x-blue.svg)](https://www.python.org/)
4+
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
5+
6+
Sync your forked GitHub repository with the upstream/original repo using one command.
7+
8+
## 🚀 Features
9+
10+
- Automatically adds the `upstream` remote (if not present)
11+
- Fetches updates from upstream
12+
- Merges/rebases upstream into your fork's main branch
13+
- Pushes changes to your GitHub fork
14+
15+
## 📦 Installation
16+
17+
```bash
18+
pip install -r requirements.txt
19+
```
20+
21+
## 🛠️ Usage
22+
23+
```bash
24+
python gh_fork_sync.py --repo owner/repo --token YOUR_GITHUB_TOKEN
25+
```
26+
27+
**Options:**
28+
- `--branch`: Branch to sync (default: main)
29+
- `--method`: Merge or rebase (default: merge)
30+
31+
## 📄 License
32+
33+
MIT License

gh_fork_sync.py

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import argparse
2+
import subprocess
3+
import os
4+
from git import Repo, GitCommandError
5+
6+
def sync_fork(repo_path, remote_url, branch="main", method="merge"):
7+
try:
8+
repo = Repo(repo_path)
9+
origin = repo.remotes.origin
10+
if "upstream" not in [r.name for r in repo.remotes]:
11+
upstream_url = f"https://github.com/{remote_url}.git"
12+
repo.create_remote("upstream", upstream_url)
13+
print(f"Added upstream: {upstream_url}")
14+
15+
upstream = repo.remotes.upstream
16+
upstream.fetch()
17+
print(f"Fetched upstream/{branch}")
18+
19+
repo.git.checkout(branch)
20+
21+
if method == "merge":
22+
repo.git.merge(f"upstream/{branch}")
23+
print(f"Merged upstream/{branch} into {branch}")
24+
else:
25+
repo.git.rebase(f"upstream/{branch}")
26+
print(f"Rebased {branch} with upstream/{branch}")
27+
28+
origin.push()
29+
print("Pushed changes to origin.")
30+
31+
except GitCommandError as e:
32+
print(f"Git error: {e}")
33+
except Exception as ex:
34+
print(f"Error: {ex}")
35+
36+
def main():
37+
parser = argparse.ArgumentParser(description="Sync fork with upstream")
38+
parser.add_argument("--repo", required=True, help="Repo path in format 'owner/repo'")
39+
parser.add_argument("--token", help="GitHub token (not used in local-only operations)")
40+
parser.add_argument("--branch", default="main", help="Branch to sync (default: main)")
41+
parser.add_argument("--method", choices=["merge", "rebase"], default="merge", help="Sync method (merge or rebase)")
42+
parser.add_argument("--local", default=".", help="Local path to the fork repo")
43+
args = parser.parse_args()
44+
45+
sync_fork(args.local, args.repo, args.branch, args.method)
46+
47+
if __name__ == "__main__":
48+
main()

requirements.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
GitPython

setup.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
from setuptools import setup
2+
3+
setup(
4+
name='gh_fork_sync',
5+
version='0.1',
6+
py_modules=['gh_fork_sync'],
7+
install_requires=['GitPython'],
8+
entry_points={
9+
'console_scripts': [
10+
'gh-fork-sync=gh_fork_sync:main',
11+
],
12+
},
13+
author='Shripad Bankar',
14+
description='Sync GitHub fork with upstream repo via CLI',
15+
license='MIT',
16+
classifiers=[
17+
'Programming Language :: Python :: 3',
18+
'License :: OSI Approved :: MIT License'
19+
],
20+
)

0 commit comments

Comments
 (0)