Skip to content

WIP Quick doc #1608

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 38 commits into from
Jul 20, 2023
Merged
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
97cdb40
Made the init repo section of quickdoc
LeoDaCoda Jul 8, 2023
6a9154b
Added git clone & git add
LeoDaCoda Jul 9, 2023
3c42bae
Finishing touches for Repo quickstart
LeoDaCoda Jul 9, 2023
10ea113
finished code for quickstart
LeoDaCoda Jul 10, 2023
b0da0a9
finished code for quickstart
LeoDaCoda Jul 10, 2023
fb35ed1
fixed some indentation
LeoDaCoda Jul 10, 2023
d42d82e
Merge remote-tracking branch 'origin/quick_doc' into quick_doc
LeoDaCoda Jul 10, 2023
47c8362
added quickstart to toctree and fixed sphinx warning
LeoDaCoda Jul 10, 2023
b7955ed
added quickstart to toctree to fix sphinx warning
LeoDaCoda Jul 10, 2023
4534f84
Merge remote-tracking branch 'origin/quick_doc' into quick_doc
LeoDaCoda Jul 10, 2023
03d26f0
Removed code from RST
LeoDaCoda Jul 10, 2023
a0045d8
Made variable names more intuitive
LeoDaCoda Jul 10, 2023
9833655
Updated the sample repo URL
LeoDaCoda Jul 10, 2023
3cda530
removed try/except and updated sample url
LeoDaCoda Jul 10, 2023
e4bbc7a
correct way to get the latest commit tree
LeoDaCoda Jul 10, 2023
a1dfd4a
convert from --all flag to all=True
LeoDaCoda Jul 11, 2023
a8b5863
removed unnecessary variables
LeoDaCoda Jul 11, 2023
abe7e6e
replaced output cell to generic commit ID
LeoDaCoda Jul 11, 2023
1369bdc
replaced hash with generic
LeoDaCoda Jul 13, 2023
9cd9431
draft of description
LeoDaCoda Jul 13, 2023
393bae5
clarified comment
LeoDaCoda Jul 13, 2023
aa6d27f
refactored print git tree
LeoDaCoda Jul 13, 2023
6d78ff1
Made trees and blobs the first section
LeoDaCoda Jul 16, 2023
2c9c0c1
Added warning about index add
LeoDaCoda Jul 16, 2023
d276107
Updated generic sha hash
LeoDaCoda Jul 16, 2023
f3968f2
Removed all reference to source code
LeoDaCoda Jul 16, 2023
9ca25d7
WIP major changes to structure to improve readability
LeoDaCoda Jul 16, 2023
7fa57e5
Added new section to print prev file
LeoDaCoda Jul 16, 2023
9d878af
change to formatting - removed = bash cmds
LeoDaCoda Jul 17, 2023
315405d
formatting wip
LeoDaCoda Jul 17, 2023
bccf8bc
added new section for diffs and formatting
LeoDaCoda Jul 18, 2023
cad1e2e
tabbed all code-blocks
LeoDaCoda Jul 18, 2023
7e589f3
fixed tabbing
LeoDaCoda Jul 18, 2023
2a45f94
redundant line
LeoDaCoda Jul 18, 2023
ef4d6d5
redundant code cell
LeoDaCoda Jul 18, 2023
8138b3a
generic hash
LeoDaCoda Jul 18, 2023
84885a3
added more resources section
LeoDaCoda Jul 19, 2023
cf3a899
typo
LeoDaCoda Jul 19, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions doc/source/index.rst
Original file line number Diff line number Diff line change
@@ -9,6 +9,7 @@ GitPython Documentation
:maxdepth: 2

intro
quickstart
tutorial
reference
roadmap
244 changes: 244 additions & 0 deletions doc/source/quickstart.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,244 @@
.. _quickdoc_toplevel:

.. highlight:: python

.. _quickdoc-label:

==============================
GitPython Quick Start Tutorial
==============================
Welcome to the GitPython Quickstart Guide! Designed for developers seeking a practical and interactive learning experience, this concise resource offers step-by-step code snippets to swiftly initialize/clone repositories, perform essential Git operations, and explore GitPython's capabilities. Get ready to dive in, experiment, and unleash the power of GitPython in your projects!


git.Repo
********

There are a few ways to create a :class:`git.Repo <git.repo.base.Repo>` object

Initialize a new git Repo
#########################

.. literalinclude:: ../../test/test_quick_doc.py
:language: python
:dedent: 8
:start-after: # [1-test_init_repo_object]
:end-before: # ![1-test_init_repo_object]

Existing local git Repo
#######################

.. literalinclude:: ../../test/test_quick_doc.py
:language: python
:dedent: 8
:start-after: # [2-test_init_repo_object]
:end-before: # ![2-test_init_repo_object]

Clone from URL
##############

For the rest of this tutorial we will use a clone from https://github.com/gitpython-developers/QuickStartTutorialFiles.git

.. literalinclude:: ../../test/test_quick_doc.py
:language: python
:dedent: 8
:start-after: # [1-test_cloned_repo_object]
:end-before: # ![1-test_cloned_repo_object]


Trees & Blobs
**************

Latest Commit Tree
##################

.. literalinclude:: ../../test/test_quick_doc.py
:language: python
:dedent: 8
:start-after: # [12-test_cloned_repo_object]
:end-before: # ![12-test_cloned_repo_object]

Any Commit Tree
###############

.. literalinclude:: ../../test/test_quick_doc.py
:language: python
:dedent: 8
:start-after: # [13-test_cloned_repo_object]
:end-before: # ![13-test_cloned_repo_object]

Display level 1 Contents
########################

.. literalinclude:: ../../test/test_quick_doc.py
:language: python
:dedent: 8
:start-after: # [14-test_cloned_repo_object]
:end-before: # ![14-test_cloned_repo_object]

Recurse through the Tree
########################

.. literalinclude:: ../../test/test_quick_doc.py
:language: python
:dedent: 8
:start-after: # [15-test_cloned_repo_object]
:end-before: # ![15-test_cloned_repo_object]

.. literalinclude:: ../../test/test_quick_doc.py
:language: python
:dedent: 8
:start-after: # [16-test_cloned_repo_object]
:end-before: # ![16-test_cloned_repo_object]




Usage
****************

Add file to staging area
########################


.. literalinclude:: ../../test/test_quick_doc.py
:language: python
:dedent: 8
:start-after: # [2-test_cloned_repo_object]
:end-before: # ![2-test_cloned_repo_object]

Now lets add the updated file to git

.. literalinclude:: ../../test/test_quick_doc.py
:language: python
:dedent: 8
:start-after: # [3-test_cloned_repo_object]
:end-before: # ![3-test_cloned_repo_object]

Notice the add method requires a list as a parameter

Warning: If you experience any trouble with this, try to invoke :class:`git <git.cmd.Git>` instead via repo.git.add(path)

Commit
######

.. literalinclude:: ../../test/test_quick_doc.py
:language: python
:dedent: 8
:start-after: # [4-test_cloned_repo_object]
:end-before: # ![4-test_cloned_repo_object]

List of commits associated with a file
#######################################

.. literalinclude:: ../../test/test_quick_doc.py
:language: python
:dedent: 8
:start-after: # [5-test_cloned_repo_object]
:end-before: # ![5-test_cloned_repo_object]

Notice this returns a generator object

.. literalinclude:: ../../test/test_quick_doc.py
:language: python
:dedent: 8
:start-after: # [6-test_cloned_repo_object]
:end-before: # ![6-test_cloned_repo_object]

returns list of :class:`Commit <git.objects.commit.Commit>` objects

Printing text files
####################
Lets print the latest version of `<local_dir>/dir1/file2.txt`

.. literalinclude:: ../../test/test_quick_doc.py
:language: python
:dedent: 8
:start-after: # [17-test_cloned_repo_object]
:end-before: # ![17-test_cloned_repo_object]

.. literalinclude:: ../../test/test_quick_doc.py
:language: python
:dedent: 8
:start-after: # [18-test_cloned_repo_object]
:end-before: # ![18-test_cloned_repo_object]

Previous version of `<local_dir>/dir1/file2.txt`

.. literalinclude:: ../../test/test_quick_doc.py
:language: python
:dedent: 8
:start-after: # [18.1-test_cloned_repo_object]
:end-before: # ![18.1-test_cloned_repo_object]

Status
######
* Untracked files

Lets create a new file

.. literalinclude:: ../../test/test_quick_doc.py
:language: python
:dedent: 8
:start-after: # [7-test_cloned_repo_object]
:end-before: # ![7-test_cloned_repo_object]

.. literalinclude:: ../../test/test_quick_doc.py
:language: python
:dedent: 8
:start-after: # [8-test_cloned_repo_object]
:end-before: # ![8-test_cloned_repo_object]

* Modified files

.. literalinclude:: ../../test/test_quick_doc.py
:language: python
:dedent: 8
:start-after: # [9-test_cloned_repo_object]
:end-before: # ![9-test_cloned_repo_object]

.. literalinclude:: ../../test/test_quick_doc.py
:language: python
:dedent: 8
:start-after: # [10-test_cloned_repo_object]
:end-before: # ![10-test_cloned_repo_object]

returns a list of :class:`Diff <git.diff.Diff>` objects

.. literalinclude:: ../../test/test_quick_doc.py
:language: python
:dedent: 8
:start-after: # [11-test_cloned_repo_object]
:end-before: # ![11-test_cloned_repo_object]

Diffs
######

Compare staging area to head commit

.. literalinclude:: ../../test/test_quick_doc.py
:language: python
:dedent: 8
:start-after: # [11.1-test_cloned_repo_object]
:end-before: # ![11.1-test_cloned_repo_object]

.. literalinclude:: ../../test/test_quick_doc.py
:language: python
:dedent: 8
:start-after: # [11.2-test_cloned_repo_object]
:end-before: # ![11.2-test_cloned_repo_object]

Compare commit to commit

.. literalinclude:: ../../test/test_quick_doc.py
:language: python
:dedent: 8
:start-after: # [11.3-test_cloned_repo_object]
:end-before: # ![11.3-test_cloned_repo_object]


More Resources
****************

Remember, this is just the beginning! There's a lot more you can achieve with GitPython in your development workflow.
To explore further possibilities and discover advanced features, check out the full :ref:`GitPython tutorial <tutorial_toplevel>`
and the :ref:`API Reference <api_reference_toplevel>`. Happy coding!
224 changes: 224 additions & 0 deletions test/test_quick_doc.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,224 @@
import pytest


from test.lib import TestBase
from test.lib.helper import with_rw_directory


class QuickDoc(TestBase):
def tearDown(self):
import gc

gc.collect()

@with_rw_directory
def test_init_repo_object(self, path_to_dir):

# [1-test_init_repo_object]
# $ git init <path/to/dir>

from git import Repo

repo = Repo.init(path_to_dir)
# ![1-test_init_repo_object]

# [2-test_init_repo_object]
repo = Repo(path_to_dir)
# ![2-test_init_repo_object]

@with_rw_directory
def test_cloned_repo_object(self, local_dir):

from git import Repo
import git
# code to clone from url
# [1-test_cloned_repo_object]
# $ git clone <url> <local_dir>

repo_url = "https://github.com/gitpython-developers/QuickStartTutorialFiles.git"

repo = Repo.clone_from(repo_url, local_dir)
# ![1-test_cloned_repo_object]

# code to add files
# [2-test_cloned_repo_object]
# We must make a change to a file so that we can add the update to git

update_file = 'dir1/file2.txt' # we'll use local_dir/dir1/file2.txt
with open(f"{local_dir}/{update_file}", 'a') as f:
f.write('\nUpdate version 2')
# ![2-test_cloned_repo_object]

# [3-test_cloned_repo_object]
# $ git add <file>
add_file = [update_file] # relative path from git root
repo.index.add(add_file) # notice the add function requires a list of paths
# ![3-test_cloned_repo_object]

# code to commit - not sure how to test this
# [4-test_cloned_repo_object]
# $ git commit -m <message>
repo.index.commit("Update to file2")
# ![4-test_cloned_repo_object]

# [5-test_cloned_repo_object]
# $ git log <file>

# relative path from git root
repo.iter_commits(all=True, max_count=10, paths=update_file) # gets the last 10 commits from all branches

# Outputs: <generator object Commit._iter_from_process_or_stream at 0x7fb66c186cf0>

# ![5-test_cloned_repo_object]

# [6-test_cloned_repo_object]
commits_for_file_generator = repo.iter_commits(all=True, max_count=10, paths=update_file)
commits_for_file = [c for c in commits_for_file_generator]
commits_for_file

# Outputs: [<git.Commit "SHA1-HEX_HASH-2">,
# <git.Commit "SHA1-HEX-HASH-1">]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That would be "SHA1-HEX_HASH-2".

# ![6-test_cloned_repo_object]

# Untracked files - create new file
# [7-test_cloned_repo_object]
f = open(f'{local_dir}/untracked.txt', 'w') # creates an empty file
f.close()
# ![7-test_cloned_repo_object]

# [8-test_cloned_repo_object]
repo.untracked_files
# Output: ['untracked.txt']
# ![8-test_cloned_repo_object]

# Modified files
# [9-test_cloned_repo_object]
# Let's modify one of our tracked files

with open(f'{local_dir}/Downloads/file3.txt', 'w') as f:
f.write('file3 version 2') # overwrite file 3
# ![9-test_cloned_repo_object]

# [10-test_cloned_repo_object]
repo.index.diff(None) # compares staging area to working directory

# Output: [<git.diff.Diff object at 0x7fb66c076e50>,
# <git.diff.Diff object at 0x7fb66c076ca0>]
# ![10-test_cloned_repo_object]

# [11-test_cloned_repo_object]
diffs = repo.index.diff(None)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please see my previous comment.

for d in diffs:
print(d.a_path)

# Output
# Downloads/file3.txt
# ![11-test_cloned_repo_object]

# compares staging area to head commit
# [11.1-test_cloned_repo_object]
diffs = repo.index.diff(repo.head.commit)
for d in diffs:
print(d.a_path)

# Output

# ![11.1-test_cloned_repo_object]
# [11.2-test_cloned_repo_object]
# lets add untracked.txt
repo.index.add(['untracked.txt'])
diffs = repo.index.diff(repo.head.commit)
for d in diffs:
print(d.a_path)

# Output
# untracked.txt
# ![11.2-test_cloned_repo_object]

# Compare commit to commit
# [11.3-test_cloned_repo_object]
first_commit = [c for c in repo.iter_commits(all=True)][-1]
diffs = repo.head.commit.diff(first_commit)
for d in diffs:
print(d.a_path)

# Output
# dir1/file2.txt
# ![11.3-test_cloned_repo_object]



'''Trees and Blobs'''

# Latest commit tree
# [12-test_cloned_repo_object]
tree = repo.head.commit.tree
# ![12-test_cloned_repo_object]

# Previous commit tree
# [13-test_cloned_repo_object]
prev_commits = [c for c in repo.iter_commits(all=True, max_count=10)] # last 10 commits from all branches
tree = prev_commits[0].tree
# ![13-test_cloned_repo_object]

# Iterating through tree
# [14-test_cloned_repo_object]
files_and_dirs = [(entry, entry.name, entry.type) for entry in tree]
files_and_dirs

# Output
# [(< git.Tree "SHA1-HEX_HASH" >, 'Downloads', 'tree'),
# (< git.Tree "SHA1-HEX_HASH" >, 'dir1', 'tree'),
# (< git.Blob "SHA1-HEX_HASH" >, 'file4.txt', 'blob')]
# ![14-test_cloned_repo_object]

# [15-test_cloned_repo_object]
def print_files_from_git(root, level=0):
for entry in root:
print(f'{"-" * 4 * level}| {entry.path}, {entry.type}')
if entry.type == "tree":
print_files_from_git(entry, level + 1)

# ![15-test_cloned_repo_object]

# [16-test_cloned_repo_object]
print_files_from_git(tree)

# Output
# | Downloads, tree
# ----| Downloads / file3.txt, blob
# | dir1, tree
# ----| dir1 / file1.txt, blob
# ----| dir1 / file2.txt, blob
# | file4.txt, blob
# # ![16-test_cloned_repo_object]

# Printing text files
# [17-test_cloned_repo_object]
print_file = 'dir1/file2.txt'
tree[print_file] # the head commit tree

# Output <git.Blob "SHA1-HEX-HASH">
# ![17-test_cloned_repo_object]

# print latest file
# [18-test_cloned_repo_object]
blob = tree[print_file]
print(blob.data_stream.read().decode())

# Output
# file 2 version 1
# Update version 2
# ![18-test_cloned_repo_object]

# print previous tree
# [18.1-test_cloned_repo_object]
commits_for_file = [c for c in repo.iter_commits(all=True, paths=print_file)]
tree = commits_for_file[-1].tree # gets the first commit tree
blob = tree[print_file]

print(blob.data_stream.read().decode())

# Output
# file 2 version 1
# ![18.1-test_cloned_repo_object]