GitPython快速入门教程

欢迎使用GitPython快速入门指南!这个简明的资源专为寻求实用和交互式学习体验的开发人员而设计,它提供了逐步的代码片段,以快速初始化/克隆存储库、执行基本的Git操作并探索GitPython的功能。准备好深入研究、试验并在您的项目中释放GitPython的力量吧!

git.Repo

有几种方法可以创建 git.Repo 对象

初始化新的GIT回购

# $ git init <path/to/dir>

from git import Repo

repo = Repo.init(path_to_dir)

现有本地GIT回购

repo = Repo(path_to_dir)

从URL克隆

在本教程的其余部分中,我们将使用来自https://github.com/gitpython-developers/QuickStartTutorialFiles.git的克隆

# $ git clone <url> <local_dir>

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

repo = Repo.clone_from(repo_url, local_dir)

树木和树团

最新提交树

tree = repo.head.commit.tree

任何提交树

prev_commits = list(repo.iter_commits(all=True, max_count=10))  # Last 10 commits from all branches.
tree = prev_commits[0].tree

显示1级内容

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')]

在树中递归

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)

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

用法

将文件添加到临时区域

# 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")

现在,让我们将更新后的文件添加到GIT

# $ 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

请注意,Add方法需要一个列表作为参数

警告:如果您在此过程中遇到任何问题,请尝试调用 git 而是通过repo.git.add(路径)

承诺

# $ git commit -m <message>
repo.index.commit("Update to file2")

与文件关联的提交列表

# $ 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>

请注意,这将返回一个生成器对象

commits_for_file_generator = repo.iter_commits(all=True, max_count=10, paths=update_file)
commits_for_file = list(commits_for_file_generator)
commits_for_file

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

返回以下项目的列表 Commit 对象

打印文本文件

让我们打印最新版本的 <local_dir>/dir1/file2.txt

print_file = "dir1/file2.txt"
tree[print_file]  # The head commit tree.

# Output <git.Blob "SHA1-HEX-HASH">
blob = tree[print_file]
print(blob.data_stream.read().decode())

# Output
# File 2 version 1
# Update version 2

以前版本的 <local_dir>/dir1/file2.txt

commits_for_file = list(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

状态

  • 未跟踪的文件

    让我们创建一个新文件

    f = open(f"{local_dir}/untracked.txt", "w")  # Creates an empty file.
    f.close()
    
    repo.untracked_files
    # Output: ['untracked.txt']
    
  • 已修改的文件

    # 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.
    
    repo.index.diff(None)  # Compares staging area to working directory.
    
    # Output: [<git.diff.Diff object at 0x7fb66c076e50>,
    # <git.diff.Diff object at 0x7fb66c076ca0>]
    

    返回一个列表, Diff 对象

    diffs = repo.index.diff(None)
    for d in diffs:
        print(d.a_path)
    
    # Output
    # Downloads/file3.txt
    

差异

将临时区域与头部提交进行比较

diffs = repo.index.diff(repo.head.commit)
for d in diffs:
    print(d.a_path)

# Output

# Let's 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

将提交与提交进行比较

first_commit = list(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

更多资源

记住,这只是个开始!在您的开发工作流程中,使用GitPython可以实现更多的功能。要探索更多可能性并发现高级功能,请查看完整的 GitPython tutorial 以及 API Reference 。编码快乐!