githubtakeout 0.1.0__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.
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2015-2025 Corey Goldberg
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.
@@ -0,0 +1,108 @@
1
+ Metadata-Version: 2.4
2
+ Name: githubtakeout
3
+ Version: 0.1.0
4
+ Summary: Archive public Git Repos and Gists from GitHub
5
+ Author: Corey Goldberg
6
+ Maintainer: Corey Goldberg
7
+ License-Expression: MIT
8
+ Project-URL: homepage, https://github.com/cgoldberg/githubtakeout
9
+ Project-URL: source, https://github.com/cgoldberg/githubtakeout
10
+ Project-URL: download, https://pypi.org/project/githubtakeout
11
+ Keywords: git,github,archive,backup,export,takeout
12
+ Classifier: Environment :: Console
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: Programming Language :: Python
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3.9
17
+ Classifier: Programming Language :: Python :: 3.10
18
+ Classifier: Programming Language :: Python :: 3.11
19
+ Classifier: Programming Language :: Python :: 3.12
20
+ Classifier: Programming Language :: Python :: 3.13
21
+ Requires-Python: >=3.9
22
+ Description-Content-Type: text/markdown
23
+ License-File: LICENSE
24
+ Requires-Dist: GitPython==3.1.44
25
+ Requires-Dist: PyGithub==2.6.1
26
+ Dynamic: license-file
27
+
28
+ # githubtakeout
29
+
30
+ ## Archive public Git Repos and Gists from GitHub
31
+
32
+ ---
33
+
34
+ - Copyright (c) 2015-2025 [Corey Goldberg](https://github.com/cgoldberg)
35
+ - License: [MIT](https://raw.githubusercontent.com/cgoldberg/githubtakeout/refs/heads/master/LICENSE)
36
+ - Development: [GitHub](https://github.com/cgoldberg/githubtakeout)
37
+ - Download/Install: [PyPI](https://pypi.org/project/githubtakeout)
38
+
39
+ ----
40
+
41
+ ## About:
42
+
43
+ `githubtakeout` is a data export tool for archiving Git repositories hosted on GitHub.
44
+ It clones a user's public repos and creates an archive of each.
45
+
46
+ By default, it doesn't save commit history or branches (`.git` directory), or Gist
47
+ repositories (both can be enabled with command line options). It also doesn't access
48
+ private repositories or secret gists.
49
+
50
+ When you run the program, archives of your repos will be saved in a directory named
51
+ `backups` inside your current working directory, unless a different location is specified
52
+ using the `--dir` option.
53
+
54
+ Archives are saved in compressed zip format (`.zip`) by default, but can also be saved
55
+ as tarballs (`.tar.gz`) using the `--format=tar` option.
56
+
57
+ ## Requirements:
58
+
59
+ - Python 3.9+
60
+ - Git 1.7+
61
+ - Python packages:
62
+ - GitPython
63
+ - PyGithub
64
+
65
+ ## Installing and Running:
66
+
67
+ ### Install from PyPI:
68
+
69
+ ```
70
+ pip install githubtakeout
71
+ ```
72
+
73
+ ### Create/Activate Virtual Environment, Install from PyPI, Run:
74
+
75
+ ```
76
+ python3 -m venv venv
77
+ source venv/bin/activate
78
+ pip install githubtakeout
79
+ githubtakeout <github username>
80
+ ```
81
+
82
+ ### Clone Repo, Create/Activate Virtual Environment, Install from Source, Run:
83
+
84
+ ```
85
+ git clone git@github.com:cgoldberg/githubtakeout.git
86
+ cd ./githubtakeout
87
+ python3 -m venv venv
88
+ source venv/bin/activate
89
+ pip install .
90
+ githubtakeout <github username>
91
+ ```
92
+
93
+ ### Usage:
94
+
95
+ ```
96
+ usage: githubtakeout [-h] [--dir DIR] [--format FORMAT] [--gists] [--history] [--list] username
97
+
98
+ positional arguments:
99
+ username GitHub username
100
+
101
+ options:
102
+ -h, --help show this help message and exit
103
+ --dir DIR output directory
104
+ --format FORMAT archive format (tar, zip)
105
+ --gists include gists
106
+ --history include commit history and branches (.git directory)
107
+ --list list repos only
108
+ ```
@@ -0,0 +1,81 @@
1
+ # githubtakeout
2
+
3
+ ## Archive public Git Repos and Gists from GitHub
4
+
5
+ ---
6
+
7
+ - Copyright (c) 2015-2025 [Corey Goldberg](https://github.com/cgoldberg)
8
+ - License: [MIT](https://raw.githubusercontent.com/cgoldberg/githubtakeout/refs/heads/master/LICENSE)
9
+ - Development: [GitHub](https://github.com/cgoldberg/githubtakeout)
10
+ - Download/Install: [PyPI](https://pypi.org/project/githubtakeout)
11
+
12
+ ----
13
+
14
+ ## About:
15
+
16
+ `githubtakeout` is a data export tool for archiving Git repositories hosted on GitHub.
17
+ It clones a user's public repos and creates an archive of each.
18
+
19
+ By default, it doesn't save commit history or branches (`.git` directory), or Gist
20
+ repositories (both can be enabled with command line options). It also doesn't access
21
+ private repositories or secret gists.
22
+
23
+ When you run the program, archives of your repos will be saved in a directory named
24
+ `backups` inside your current working directory, unless a different location is specified
25
+ using the `--dir` option.
26
+
27
+ Archives are saved in compressed zip format (`.zip`) by default, but can also be saved
28
+ as tarballs (`.tar.gz`) using the `--format=tar` option.
29
+
30
+ ## Requirements:
31
+
32
+ - Python 3.9+
33
+ - Git 1.7+
34
+ - Python packages:
35
+ - GitPython
36
+ - PyGithub
37
+
38
+ ## Installing and Running:
39
+
40
+ ### Install from PyPI:
41
+
42
+ ```
43
+ pip install githubtakeout
44
+ ```
45
+
46
+ ### Create/Activate Virtual Environment, Install from PyPI, Run:
47
+
48
+ ```
49
+ python3 -m venv venv
50
+ source venv/bin/activate
51
+ pip install githubtakeout
52
+ githubtakeout <github username>
53
+ ```
54
+
55
+ ### Clone Repo, Create/Activate Virtual Environment, Install from Source, Run:
56
+
57
+ ```
58
+ git clone git@github.com:cgoldberg/githubtakeout.git
59
+ cd ./githubtakeout
60
+ python3 -m venv venv
61
+ source venv/bin/activate
62
+ pip install .
63
+ githubtakeout <github username>
64
+ ```
65
+
66
+ ### Usage:
67
+
68
+ ```
69
+ usage: githubtakeout [-h] [--dir DIR] [--format FORMAT] [--gists] [--history] [--list] username
70
+
71
+ positional arguments:
72
+ username GitHub username
73
+
74
+ options:
75
+ -h, --help show this help message and exit
76
+ --dir DIR output directory
77
+ --format FORMAT archive format (tar, zip)
78
+ --gists include gists
79
+ --history include commit history and branches (.git directory)
80
+ --list list repos only
81
+ ```
@@ -0,0 +1,108 @@
1
+ Metadata-Version: 2.4
2
+ Name: githubtakeout
3
+ Version: 0.1.0
4
+ Summary: Archive public Git Repos and Gists from GitHub
5
+ Author: Corey Goldberg
6
+ Maintainer: Corey Goldberg
7
+ License-Expression: MIT
8
+ Project-URL: homepage, https://github.com/cgoldberg/githubtakeout
9
+ Project-URL: source, https://github.com/cgoldberg/githubtakeout
10
+ Project-URL: download, https://pypi.org/project/githubtakeout
11
+ Keywords: git,github,archive,backup,export,takeout
12
+ Classifier: Environment :: Console
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: Programming Language :: Python
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3.9
17
+ Classifier: Programming Language :: Python :: 3.10
18
+ Classifier: Programming Language :: Python :: 3.11
19
+ Classifier: Programming Language :: Python :: 3.12
20
+ Classifier: Programming Language :: Python :: 3.13
21
+ Requires-Python: >=3.9
22
+ Description-Content-Type: text/markdown
23
+ License-File: LICENSE
24
+ Requires-Dist: GitPython==3.1.44
25
+ Requires-Dist: PyGithub==2.6.1
26
+ Dynamic: license-file
27
+
28
+ # githubtakeout
29
+
30
+ ## Archive public Git Repos and Gists from GitHub
31
+
32
+ ---
33
+
34
+ - Copyright (c) 2015-2025 [Corey Goldberg](https://github.com/cgoldberg)
35
+ - License: [MIT](https://raw.githubusercontent.com/cgoldberg/githubtakeout/refs/heads/master/LICENSE)
36
+ - Development: [GitHub](https://github.com/cgoldberg/githubtakeout)
37
+ - Download/Install: [PyPI](https://pypi.org/project/githubtakeout)
38
+
39
+ ----
40
+
41
+ ## About:
42
+
43
+ `githubtakeout` is a data export tool for archiving Git repositories hosted on GitHub.
44
+ It clones a user's public repos and creates an archive of each.
45
+
46
+ By default, it doesn't save commit history or branches (`.git` directory), or Gist
47
+ repositories (both can be enabled with command line options). It also doesn't access
48
+ private repositories or secret gists.
49
+
50
+ When you run the program, archives of your repos will be saved in a directory named
51
+ `backups` inside your current working directory, unless a different location is specified
52
+ using the `--dir` option.
53
+
54
+ Archives are saved in compressed zip format (`.zip`) by default, but can also be saved
55
+ as tarballs (`.tar.gz`) using the `--format=tar` option.
56
+
57
+ ## Requirements:
58
+
59
+ - Python 3.9+
60
+ - Git 1.7+
61
+ - Python packages:
62
+ - GitPython
63
+ - PyGithub
64
+
65
+ ## Installing and Running:
66
+
67
+ ### Install from PyPI:
68
+
69
+ ```
70
+ pip install githubtakeout
71
+ ```
72
+
73
+ ### Create/Activate Virtual Environment, Install from PyPI, Run:
74
+
75
+ ```
76
+ python3 -m venv venv
77
+ source venv/bin/activate
78
+ pip install githubtakeout
79
+ githubtakeout <github username>
80
+ ```
81
+
82
+ ### Clone Repo, Create/Activate Virtual Environment, Install from Source, Run:
83
+
84
+ ```
85
+ git clone git@github.com:cgoldberg/githubtakeout.git
86
+ cd ./githubtakeout
87
+ python3 -m venv venv
88
+ source venv/bin/activate
89
+ pip install .
90
+ githubtakeout <github username>
91
+ ```
92
+
93
+ ### Usage:
94
+
95
+ ```
96
+ usage: githubtakeout [-h] [--dir DIR] [--format FORMAT] [--gists] [--history] [--list] username
97
+
98
+ positional arguments:
99
+ username GitHub username
100
+
101
+ options:
102
+ -h, --help show this help message and exit
103
+ --dir DIR output directory
104
+ --format FORMAT archive format (tar, zip)
105
+ --gists include gists
106
+ --history include commit history and branches (.git directory)
107
+ --list list repos only
108
+ ```
@@ -0,0 +1,10 @@
1
+ LICENSE
2
+ README.md
3
+ githubtakeout.py
4
+ pyproject.toml
5
+ githubtakeout.egg-info/PKG-INFO
6
+ githubtakeout.egg-info/SOURCES.txt
7
+ githubtakeout.egg-info/dependency_links.txt
8
+ githubtakeout.egg-info/entry_points.txt
9
+ githubtakeout.egg-info/requires.txt
10
+ githubtakeout.egg-info/top_level.txt
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ githubtakeout = githubtakeout:main
@@ -0,0 +1,2 @@
1
+ GitPython==3.1.44
2
+ PyGithub==2.6.1
@@ -0,0 +1 @@
1
+ githubtakeout
@@ -0,0 +1,164 @@
1
+ #!/usr/bin/env python3
2
+
3
+ import argparse
4
+ import logging
5
+ import os
6
+ import shutil
7
+ import tarfile
8
+ import zipfile
9
+
10
+ from pathlib import Path
11
+ from timeit import default_timer
12
+
13
+ import git
14
+ import github
15
+
16
+
17
+ logging.basicConfig(level=logging.INFO, format='%(message)s')
18
+ logger = logging.getLogger(__name__)
19
+
20
+
21
+ def archive(local_repo_dir, archive_format='zip', is_gist=False):
22
+ if archive_format not in ('tar', 'zip'):
23
+ raise ValueError(f'{archive_format} is not a valid archive format')
24
+ base_name = os.path.basename(local_repo_dir)
25
+ extension = 'tar.gz' if archive_format == 'tar' else archive_format
26
+ archive_name = f'{base_name}.{extension}'
27
+ if is_gist:
28
+ archive_name = f'gist-{archive_name}'
29
+ parent_dir = os.path.dirname(local_repo_dir)
30
+ archive_path = os.path.join(parent_dir, archive_name)
31
+ logger.info(f'creating archive: {archive_path}')
32
+ if archive_format == 'tar':
33
+ with tarfile.open(archive_path, 'w:gz') as tar:
34
+ tar.add(local_repo_dir, arcname=base_name)
35
+ elif archive_format == 'zip':
36
+ with zipfile.ZipFile(archive_path, 'w', zipfile.ZIP_DEFLATED) as zip:
37
+ repo_path = Path(local_repo_dir)
38
+ for entry in repo_path.rglob('*'):
39
+ path = os.path.join(base_name, entry.relative_to(repo_path))
40
+ zip.write(entry, arcname=path)
41
+ return archive_path
42
+
43
+
44
+ def clone_and_archive_repo(repo_url, local_repo_dir, archive_format, include_history, is_gist=False):
45
+ try:
46
+ shutil.rmtree(local_repo_dir)
47
+ except FileNotFoundError:
48
+ pass
49
+ logger.info(f'cloning repo: {repo_url} to {local_repo_dir}')
50
+ start = default_timer()
51
+ try:
52
+ if include_history:
53
+ git.Repo.clone_from(repo_url, local_repo_dir)
54
+ else:
55
+ # shallow clone (no commit history or branches)
56
+ git.Repo.clone_from(repo_url, local_repo_dir, multi_options=['--depth=1'])
57
+ try:
58
+ shutil.rmtree(os.path.join(local_repo_dir, '.git'))
59
+ except FileNotFoundError:
60
+ pass
61
+ except git.GitCommandError as e:
62
+ logger.error(e)
63
+ return
64
+ elapsed = default_timer() - start
65
+ logger.info(f'elapsed time: {elapsed:.3f} secs')
66
+ archive_path = archive(local_repo_dir, archive_format, is_gist)
67
+ size_kb = os.path.getsize(archive_path) / 1024
68
+ logger.info(f'archive size: {size_kb:.2f} KB')
69
+ logger.info('deleting repo')
70
+ try:
71
+ shutil.rmtree(local_repo_dir)
72
+ except FileNotFoundError:
73
+ pass
74
+ logger.info('')
75
+
76
+ def run(username, base_dir, archive_format, include_gists, include_history, list):
77
+ working_dir = os.path.join(base_dir, 'backups')
78
+ gh = github.Github()
79
+ try:
80
+ user = gh.get_user(username)
81
+ except github.GithubException:
82
+ print(f'Error: user "{username}" not found on GitHub')
83
+ exit(1)
84
+ repos = user.get_repos()
85
+ num_repos = len([1 for _ in repos])
86
+ if not list:
87
+ logger.info(f'creating archives in: {working_dir}\n')
88
+ logger.info(f'found {num_repos} repos for user "{username}"\n')
89
+ for repo in repos:
90
+ local_repo_dir = os.path.join(working_dir, repo.name)
91
+ if list:
92
+ logger.info(repo.clone_url)
93
+ else:
94
+ clone_and_archive_repo(
95
+ repo.clone_url,
96
+ local_repo_dir,
97
+ archive_format,
98
+ include_history
99
+ )
100
+ if include_gists:
101
+ gists = user.get_gists()
102
+ num_gists = len([1 for _ in gists])
103
+ logger.info('')
104
+ logger.info(f'found {num_gists} gists for user "{username}"\n')
105
+ for gist in gists:
106
+ local_repo_dir = os.path.join(working_dir, gist.id)
107
+ if list:
108
+ logger.info(gist.git_pull_url)
109
+ else:
110
+ clone_and_archive_repo(
111
+ gist.git_pull_url,
112
+ local_repo_dir,
113
+ archive_format,
114
+ include_history,
115
+ is_gist=True
116
+ )
117
+
118
+ def main():
119
+ parser = argparse.ArgumentParser()
120
+ parser.add_argument(
121
+ 'username',
122
+ help='GitHub username'
123
+ )
124
+ parser.add_argument(
125
+ '--dir',
126
+ default=os.getcwd(),
127
+ help='output directory'
128
+ )
129
+ parser.add_argument(
130
+ '--format',
131
+ default='zip',
132
+ help='archive format (tar, zip)'
133
+ )
134
+ parser.add_argument(
135
+ '--gists',
136
+ default=False,
137
+ action='store_true',
138
+ help='include gists'
139
+ )
140
+ parser.add_argument(
141
+ '--history',
142
+ default=False,
143
+ action='store_true',
144
+ help='include commit history and branches (.git directory)'
145
+ )
146
+ parser.add_argument(
147
+ '--list',
148
+ default=False,
149
+ action='store_true',
150
+ help='list repos only'
151
+ )
152
+ args = parser.parse_args()
153
+ run(
154
+ username=args.username,
155
+ base_dir=args.dir,
156
+ archive_format=args.format,
157
+ include_gists=args.gists,
158
+ include_history=args.history,
159
+ list=args.list
160
+ )
161
+
162
+
163
+ if __name__ == '__main__':
164
+ main()
@@ -0,0 +1,38 @@
1
+ [build-system]
2
+ requires = ["setuptools"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "githubtakeout"
7
+ version = "0.1.0"
8
+ description = "Archive public Git Repos and Gists from GitHub"
9
+ license = "MIT"
10
+ license-files = ["LICENSE"]
11
+ authors = [{name = "Corey Goldberg"}]
12
+ maintainers = [{name = "Corey Goldberg"}]
13
+ readme = "README.md"
14
+ requires-python = ">=3.9"
15
+ keywords = ["git", "github", "archive", "backup", "export", "takeout"]
16
+ classifiers = [
17
+ "Environment :: Console",
18
+ "Intended Audience :: Developers",
19
+ "Programming Language :: Python",
20
+ "Programming Language :: Python :: 3",
21
+ "Programming Language :: Python :: 3.9",
22
+ "Programming Language :: Python :: 3.10",
23
+ "Programming Language :: Python :: 3.11",
24
+ "Programming Language :: Python :: 3.12",
25
+ "Programming Language :: Python :: 3.13"
26
+ ]
27
+ dependencies = [
28
+ "GitPython==3.1.44",
29
+ "PyGithub==2.6.1"
30
+ ]
31
+
32
+ [project.scripts]
33
+ githubtakeout = "githubtakeout:main"
34
+
35
+ [project.urls]
36
+ homepage = "https://github.com/cgoldberg/githubtakeout"
37
+ source = "https://github.com/cgoldberg/githubtakeout"
38
+ download = "https://pypi.org/project/githubtakeout"
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+