Hướng dẫn python git - python git

Hướng dẫn lập trình python

Bài viết nhắm tới những người chưa có kinh nghiệm lập trình. Hi vọng bạn sẽ dễ hiểu! Thông thường thì mình sẽ code phần lớn theo tiếng Anh nhưng trong hướng dẫn này mình sẽ cố gắng thay thế bằng Tiếng Việt nhiều hơn.

Lưu ý Python hiện tại có hai phiên bản thông dụng là Python 2 và Python 3. Ở hướng dẫn này mình sẽ sử dụng Python 3.

Cách sử dụng hướng dẫn hiệu quả

  • Chạy thử code mẫu trong ví dụ (gõ lại sẽ tốt hơn là chỉ copy paste đó).
  • Đọc code và giải thích lại các dòng code.
  • Nếu thấy gì lạ mà không có trong hướng dẫn, hãy thử xem lại phần trước đó xem.
  • Google luôn hỗ trợ bạn học dễ hơn (nhưng thường là cần chút Tiếng Anh).

Nội dung

Hướng dẫn này gồm các phần sau (sẽ update dần). Giúp bạn bắt đầu với Python. Sau đó bạn có thể học sâu hơn tùy thích. Do IDLE hỗ trợ UNICODE kém quá, không gõ trực tiếp Tiếng Việt vào được, nên các comment Tiếng Việt giải thích trong bài viết ở IDE khác, không phải IDLE. Bạn có thể thử IDE khác đơn giản như Notepad++, còn nếu không thì Tiếng Việt không dấu hay Tiếng Anh cho hợp vậy.

Cơ bản

  1. Cài đặt Python
  2. Bắt đầu với Python
  3. Các loại biến và so sánh
  4. Cấu trúc lựa chọn if, else and elif
  5. Sử dụng functions
  6. String
  7. Lists và tuples
  8. Vòng lặp

Gitpython

Gitpython cung cấp quyền truy cập mô hình đối tượng vào kho lưu trữ Git của bạn. Hướng dẫn này bao gồm nhiều phần, hầu hết trong số đó giải thích một trường hợp sử dụng thực tế.

Tất cả mã được trình bày ở đây có nguồn gốc từ Test_Docs.py để đảm bảo tính chính xác. Biết điều này cũng sẽ cho phép bạn dễ dàng chạy mã hơn cho mục đích thử nghiệm của riêng bạn. Tất cả những gì bạn cần là một nhà phát triển cài đặt Git-Python.

Gặp loại repo

Bước đầu tiên là tạo một đối tượng

with open(os.path.join(rw_dir, "repo.tar"), "wb") as fp:
    repo.archive(fp)
3 để thể hiện kho lưu trữ của bạn.

from git import Repo

# rorepo is a Repo instance pointing to the git-python repository.
# For all you know, the first argument to Repo is a path to the repository
# you want to work with
repo = Repo(self.rorepo.working_tree_dir)
assert not repo.bare

Trong ví dụ trên, thư mục

with open(os.path.join(rw_dir, "repo.tar"), "wb") as fp:
    repo.archive(fp)
4 bằng
with open(os.path.join(rw_dir, "repo.tar"), "wb") as fp:
    repo.archive(fp)
5 và là kho lưu trữ hoạt động của tôi có chứa thư mục
with open(os.path.join(rw_dir, "repo.tar"), "wb") as fp:
    repo.archive(fp)
6. Bạn cũng có thể khởi tạo Gitpython với kho lưu trữ trần.

bare_repo = Repo.init(os.path.join(rw_dir, "bare-repo"), bare=True)
assert bare_repo.bare

Một đối tượng REPO cung cấp quyền truy cập cấp cao vào dữ liệu của bạn, nó cho phép bạn tạo và xóa các đầu, thẻ và điều khiển từ xa và truy cập cấu hình của kho lưu trữ.

repo.config_reader()  # get a config reader for read-only access
with repo.config_writer():  # get a config writer to change configuration
    pass  # call release() to be sure changes are written and locks are released

Truy vấn nhánh hoạt động, truy vấn chưa truy cập các tệp hoặc liệu dữ liệu kho lưu trữ đã được sửa đổi.

assert not bare_repo.is_dirty()  # check the dirty state
repo.untracked_files  # retrieve a list of untracked files
# ['my_untracked_file']

Clone từ các kho lưu trữ hiện có hoặc khởi tạo những cái trống mới.

cloned_repo = repo.clone(os.path.join(rw_dir, "to/this/path"))
assert cloned_repo.__class__ is Repo  # clone an existing repository
assert Repo.init(os.path.join(rw_dir, "path/for/new/repo")).__class__ is Repo

Lưu trữ nội dung kho lưu trữ vào một tệp tar.

with open(os.path.join(rw_dir, "repo.tar"), "wb") as fp:
    repo.archive(fp)

Sử dụng repo nâng cao

Và tất nhiên, có nhiều thứ bạn có thể làm với loại này, hầu hết những điều sau đây sẽ được giải thích chi tiết hơn trong các hướng dẫn cụ thể. Don Tiết lo lắng nếu bạn không hiểu một số ví dụ này ngay lập tức, vì chúng có thể đòi hỏi sự hiểu biết thấu đáo về hoạt động bên trong của Git.

Truy vấn các đường dẫn lưu trữ có liên quan

assert os.path.isdir(cloned_repo.working_tree_dir)  # directory with your work files
assert cloned_repo.git_dir.startswith(cloned_repo.working_tree_dir)  # directory containing the git repository
assert bare_repo.working_tree_dir is None  # bare repositories have no working tree

with open(os.path.join(rw_dir, "repo.tar"), "wb") as fp:
    repo.archive(fp)
7 Đầu là các nhánh trong git-speak.
with open(os.path.join(rw_dir, "repo.tar"), "wb") as fp:
    repo.archive(fp)
8 là gợi ý cho một cam kết cụ thể hoặc các tài liệu tham khảo khác. Đầu và
with open(os.path.join(rw_dir, "repo.tar"), "wb") as fp:
    repo.archive(fp)
9 là một loại tài liệu tham khảo. Gitpython cho phép bạn truy vấn chúng khá trực giác.

self.assertEqual(
    repo.head.ref,
    repo.heads.master,  # head is a sym-ref pointing to master
    "It's ok if TC not running from `master`.",
)
self.assertEqual(repo.tags["0.3.5"], repo.tag("refs/tags/0.3.5"))  # you can access tags in various ways too
self.assertEqual(repo.refs.master, repo.heads["master"])  # .refs provides all refs, ie heads ...

if "TRAVIS" not in os.environ:
    self.assertEqual(repo.refs["origin/master"], repo.remotes.origin.refs.master)  # ... remotes ...
self.assertEqual(repo.refs["0.3.5"], repo.tags["0.3.5"])  # ... and tags

Bạn cũng có thể tạo những cái đầu mới

new_branch = cloned_repo.create_head("feature")  # create a new branch ...
assert cloned_repo.active_branch != new_branch  # which wasn't checked out yet ...
self.assertEqual(new_branch.commit, cloned_repo.active_branch.commit)  # pointing to the checked-out commit
# It's easy to let a branch point to the previous commit, without affecting anything else
# Each reference provides access to the git object it points to, usually commits
assert new_branch.set_commit("HEAD~1").commit == cloned_repo.active_branch.commit.parents[0]

… Và thẻ

past = cloned_repo.create_tag(
    "past",
    ref=new_branch,
    message="This is a tag-object pointing to %s" % new_branch.name,
)
self.assertEqual(past.commit, new_branch.commit)  # the tag points to the specified commit
assert past.tag.message.startswith("This is")  # and its object carries the message provided

now = cloned_repo.create_tag("now")  # This is a tag-reference. It may not carry meta-data
assert now.tag is None

Bạn có thể đi qua

assert os.path.isdir(cloned_repo.working_tree_dir)  # directory with your work files
assert cloned_repo.git_dir.startswith(cloned_repo.working_tree_dir)  # directory containing the git repository
assert bare_repo.working_tree_dir is None  # bare repositories have no working tree
0 thông qua các tài liệu tham khảo và các đối tượng khác. Một số đối tượng như
assert os.path.isdir(cloned_repo.working_tree_dir)  # directory with your work files
assert cloned_repo.git_dir.startswith(cloned_repo.working_tree_dir)  # directory containing the git repository
assert bare_repo.working_tree_dir is None  # bare repositories have no working tree
1 có thêm dữ liệu meta để truy vấn.

bare_repo = Repo.init(os.path.join(rw_dir, "bare-repo"), bare=True)
assert bare_repo.bare
0

assert os.path.isdir(cloned_repo.working_tree_dir)  # directory with your work files
assert cloned_repo.git_dir.startswith(cloned_repo.working_tree_dir)  # directory containing the git repository
assert bare_repo.working_tree_dir is None  # bare repositories have no working tree
2 Cho phép xử lý các hoạt động tìm nạp, kéo và đẩy, đồng thời cung cấp thông tin tiến bộ thời gian thực tùy chọn cho
assert os.path.isdir(cloned_repo.working_tree_dir)  # directory with your work files
assert cloned_repo.git_dir.startswith(cloned_repo.working_tree_dir)  # directory containing the git repository
assert bare_repo.working_tree_dir is None  # bare repositories have no working tree
3.

bare_repo = Repo.init(os.path.join(rw_dir, "bare-repo"), bare=True)
assert bare_repo.bare
1

assert os.path.isdir(cloned_repo.working_tree_dir)  # directory with your work files
assert cloned_repo.git_dir.startswith(cloned_repo.working_tree_dir)  # directory containing the git repository
assert bare_repo.working_tree_dir is None  # bare repositories have no working tree
4 cũng được gọi là giai đoạn trong git-speak. Nó được sử dụng để chuẩn bị các cam kết mới và có thể được sử dụng để giữ kết quả của các hoạt động hợp nhất. Việc triển khai chỉ mục của chúng tôi cho phép truyền phát ngày vào chỉ mục, rất hữu ích cho các kho lưu trữ trần không có cây làm việc.

bare_repo = Repo.init(os.path.join(rw_dir, "bare-repo"), bare=True)
assert bare_repo.bare
2

assert os.path.isdir(cloned_repo.working_tree_dir)  # directory with your work files
assert cloned_repo.git_dir.startswith(cloned_repo.working_tree_dir)  # directory containing the git repository
assert bare_repo.working_tree_dir is None  # bare repositories have no working tree
5 đại diện cho tất cả các khía cạnh của các mô hình con git, cho phép bạn truy vấn tất cả các thông tin liên quan của họ và thao tác theo nhiều cách khác nhau.

bare_repo = Repo.init(os.path.join(rw_dir, "bare-repo"), bare=True)
assert bare_repo.bare
3

Kiểm tra tài liệu tham khảo bài

with open(os.path.join(rw_dir, "repo.tar"), "wb") as fp:
    repo.archive(fp)
8 là các mẹo của biểu đồ cam kết của bạn mà bạn có thể dễ dàng kiểm tra lịch sử của dự án.

bare_repo = Repo.init(os.path.join(rw_dir, "bare-repo"), bare=True)
assert bare_repo.bare
4

with open(os.path.join(rw_dir, "repo.tar"), "wb") as fp:
    repo.archive(fp)
9 là các tài liệu tham khảo (thường là bất biến) cho một đối tượng cam kết và/hoặc một đối tượng thẻ.

bare_repo = Repo.init(os.path.join(rw_dir, "bare-repo"), bare=True)
assert bare_repo.bare
5

Một

assert os.path.isdir(cloned_repo.working_tree_dir)  # directory with your work files
assert cloned_repo.git_dir.startswith(cloned_repo.working_tree_dir)  # directory containing the git repository
assert bare_repo.working_tree_dir is None  # bare repositories have no working tree
8 là một trường hợp đặc biệt của một tài liệu tham khảo vì nó chỉ vào một tài liệu tham khảo khác thay vì cam kết.

bare_repo = Repo.init(os.path.join(rw_dir, "bare-repo"), bare=True)
assert bare_repo.bare
6

Truy cập

assert os.path.isdir(cloned_repo.working_tree_dir)  # directory with your work files
assert cloned_repo.git_dir.startswith(cloned_repo.working_tree_dir)  # directory containing the git repository
assert bare_repo.working_tree_dir is None  # bare repositories have no working tree
9 một cách dễ dàng.

bare_repo = Repo.init(os.path.join(rw_dir, "bare-repo"), bare=True)
assert bare_repo.bare
7

Sửa đổi tài liệu tham khảo Jo

Bạn có thể dễ dàng tạo và xóa

self.assertEqual(
    repo.head.ref,
    repo.heads.master,  # head is a sym-ref pointing to master
    "It's ok if TC not running from `master`.",
)
self.assertEqual(repo.tags["0.3.5"], repo.tag("refs/tags/0.3.5"))  # you can access tags in various ways too
self.assertEqual(repo.refs.master, repo.heads["master"])  # .refs provides all refs, ie heads ...

if "TRAVIS" not in os.environ:
    self.assertEqual(repo.refs["origin/master"], repo.remotes.origin.refs.master)  # ... remotes ...
self.assertEqual(repo.refs["0.3.5"], repo.tags["0.3.5"])  # ... and tags
0 hoặc sửa đổi nơi họ chỉ đến.

bare_repo = Repo.init(os.path.join(rw_dir, "bare-repo"), bare=True)
assert bare_repo.bare
8

Tạo hoặc xóa

self.assertEqual(
    repo.head.ref,
    repo.heads.master,  # head is a sym-ref pointing to master
    "It's ok if TC not running from `master`.",
)
self.assertEqual(repo.tags["0.3.5"], repo.tag("refs/tags/0.3.5"))  # you can access tags in various ways too
self.assertEqual(repo.refs.master, repo.heads["master"])  # .refs provides all refs, ie heads ...

if "TRAVIS" not in os.environ:
    self.assertEqual(repo.refs["origin/master"], repo.remotes.origin.refs.master)  # ... remotes ...
self.assertEqual(repo.refs["0.3.5"], repo.tags["0.3.5"])  # ... and tags
1 theo cùng một cách ngoại trừ bạn không thể thay đổi chúng sau đó.

bare_repo = Repo.init(os.path.join(rw_dir, "bare-repo"), bare=True)
assert bare_repo.bare
9

Thay đổi

assert os.path.isdir(cloned_repo.working_tree_dir)  # directory with your work files
assert cloned_repo.git_dir.startswith(cloned_repo.working_tree_dir)  # directory containing the git repository
assert bare_repo.working_tree_dir is None  # bare repositories have no working tree
8 để chuyển nhánh với giá rẻ (mà không điều chỉnh chỉ mục hoặc cây làm việc).

repo.config_reader()  # get a config reader for read-only access
with repo.config_writer():  # get a config writer to change configuration
    pass  # call release() to be sure changes are written and locks are released
0

Hiểu đối tượng Jo

Một đối tượng là bất cứ điều gì có thể lưu trữ trong cơ sở dữ liệu đối tượng Git. Các đối tượng chứa thông tin về loại của chúng, kích thước không nén cũng như dữ liệu thực tế. Mỗi đối tượng được xác định duy nhất bởi băm SHA1 nhị phân, có kích thước 20 byte hoặc 40 byte trong ký hiệu thập lục phân.

Git chỉ biết 4 loại đối tượng riêng biệt là

self.assertEqual(
    repo.head.ref,
    repo.heads.master,  # head is a sym-ref pointing to master
    "It's ok if TC not running from `master`.",
)
self.assertEqual(repo.tags["0.3.5"], repo.tag("refs/tags/0.3.5"))  # you can access tags in various ways too
self.assertEqual(repo.refs.master, repo.heads["master"])  # .refs provides all refs, ie heads ...

if "TRAVIS" not in os.environ:
    self.assertEqual(repo.refs["origin/master"], repo.remotes.origin.refs.master)  # ... remotes ...
self.assertEqual(repo.refs["0.3.5"], repo.tags["0.3.5"])  # ... and tags
3,
self.assertEqual(
    repo.head.ref,
    repo.heads.master,  # head is a sym-ref pointing to master
    "It's ok if TC not running from `master`.",
)
self.assertEqual(repo.tags["0.3.5"], repo.tag("refs/tags/0.3.5"))  # you can access tags in various ways too
self.assertEqual(repo.refs.master, repo.heads["master"])  # .refs provides all refs, ie heads ...

if "TRAVIS" not in os.environ:
    self.assertEqual(repo.refs["origin/master"], repo.remotes.origin.refs.master)  # ... remotes ...
self.assertEqual(repo.refs["0.3.5"], repo.tags["0.3.5"])  # ... and tags
4,
self.assertEqual(
    repo.head.ref,
    repo.heads.master,  # head is a sym-ref pointing to master
    "It's ok if TC not running from `master`.",
)
self.assertEqual(repo.tags["0.3.5"], repo.tag("refs/tags/0.3.5"))  # you can access tags in various ways too
self.assertEqual(repo.refs.master, repo.heads["master"])  # .refs provides all refs, ie heads ...

if "TRAVIS" not in os.environ:
    self.assertEqual(repo.refs["origin/master"], repo.remotes.origin.refs.master)  # ... remotes ...
self.assertEqual(repo.refs["0.3.5"], repo.tags["0.3.5"])  # ... and tags
5 và
with open(os.path.join(rw_dir, "repo.tar"), "wb") as fp:
    repo.archive(fp)
9.

Trong Gitpython, tất cả các đối tượng có thể được truy cập thông qua cơ sở chung của chúng, có thể được so sánh và băm. Chúng thường không được khởi tạo trực tiếp, nhưng thông qua các tài liệu tham khảo hoặc các chức năng kho lưu trữ chuyên dụng.

repo.config_reader()  # get a config reader for read-only access
with repo.config_writer():  # get a config writer to change configuration
    pass  # call release() to be sure changes are written and locks are released
1

Các lĩnh vực chung là…

repo.config_reader()  # get a config reader for read-only access
with repo.config_writer():  # get a config writer to change configuration
    pass  # call release() to be sure changes are written and locks are released
2

self.assertEqual(
    repo.head.ref,
    repo.heads.master,  # head is a sym-ref pointing to master
    "It's ok if TC not running from `master`.",
)
self.assertEqual(repo.tags["0.3.5"], repo.tag("refs/tags/0.3.5"))  # you can access tags in various ways too
self.assertEqual(repo.refs.master, repo.heads["master"])  # .refs provides all refs, ie heads ...

if "TRAVIS" not in os.environ:
    self.assertEqual(repo.refs["origin/master"], repo.remotes.origin.refs.master)  # ... remotes ...
self.assertEqual(repo.refs["0.3.5"], repo.tags["0.3.5"])  # ... and tags
7 là các đối tượng có thể được đưa vào chỉ số Git. Những đối tượng này là cây, đốm màu và các mô hình con mà còn biết thêm về đường dẫn của chúng trong hệ thống tệp cũng như chế độ của chúng.

repo.config_reader()  # get a config reader for read-only access
with repo.config_writer():  # get a config writer to change configuration
    pass  # call release() to be sure changes are written and locks are released
3

Truy cập dữ liệu

self.assertEqual(
    repo.head.ref,
    repo.heads.master,  # head is a sym-ref pointing to master
    "It's ok if TC not running from `master`.",
)
self.assertEqual(repo.tags["0.3.5"], repo.tag("refs/tags/0.3.5"))  # you can access tags in various ways too
self.assertEqual(repo.refs.master, repo.heads["master"])  # .refs provides all refs, ie heads ...

if "TRAVIS" not in os.environ:
    self.assertEqual(repo.refs["origin/master"], repo.remotes.origin.refs.master)  # ... remotes ...
self.assertEqual(repo.refs["0.3.5"], repo.tags["0.3.5"])  # ... and tags
8 (hoặc bất kỳ dữ liệu đối tượng nào) bằng cách sử dụng các luồng.

repo.config_reader()  # get a config reader for read-only access
with repo.config_writer():  # get a config writer to change configuration
    pass  # call release() to be sure changes are written and locks are released
4

Đối tượng cam kết

self.assertEqual(
    repo.head.ref,
    repo.heads.master,  # head is a sym-ref pointing to master
    "It's ok if TC not running from `master`.",
)
self.assertEqual(repo.tags["0.3.5"], repo.tag("refs/tags/0.3.5"))  # you can access tags in various ways too
self.assertEqual(repo.refs.master, repo.heads["master"])  # .refs provides all refs, ie heads ...

if "TRAVIS" not in os.environ:
    self.assertEqual(repo.refs["origin/master"], repo.remotes.origin.refs.master)  # ... remotes ...
self.assertEqual(repo.refs["0.3.5"], repo.tags["0.3.5"])  # ... and tags
9 Đối tượng chứa thông tin về một cam kết cụ thể. Có được cam kết bằng cách sử dụng các tài liệu tham khảo như được thực hiện trong việc kiểm tra các tài liệu tham khảo hoặc như sau.

Có được cam kết tại bản sửa đổi được chỉ định

repo.config_reader()  # get a config reader for read-only access
with repo.config_writer():  # get a config writer to change configuration
    pass  # call release() to be sure changes are written and locks are released
5

Lặp lại 50 cam kết và nếu bạn cần phân trang, bạn có thể chỉ định một số cam kết bỏ qua.

repo.config_reader()  # get a config reader for read-only access
with repo.config_writer():  # get a config writer to change configuration
    pass  # call release() to be sure changes are written and locks are released
6

Một đối tượng cam kết mang tất cả các loại dữ liệu meta

repo.config_reader()  # get a config reader for read-only access
with repo.config_writer():  # get a config writer to change configuration
    pass  # call release() to be sure changes are written and locks are released
7

Lưu ý: Thời gian ngày được biểu diễn ở định dạng

new_branch = cloned_repo.create_head("feature")  # create a new branch ...
assert cloned_repo.active_branch != new_branch  # which wasn't checked out yet ...
self.assertEqual(new_branch.commit, cloned_repo.active_branch.commit)  # pointing to the checked-out commit
# It's easy to let a branch point to the previous commit, without affecting anything else
# Each reference provides access to the git object it points to, usually commits
assert new_branch.set_commit("HEAD~1").commit == cloned_repo.active_branch.commit.parents[0]
0. Chuyển đổi sang hình thức đọc có thể đọc có thể được thực hiện với các phương pháp mô -đun thời gian khác nhau.

repo.config_reader()  # get a config reader for read-only access
with repo.config_writer():  # get a config writer to change configuration
    pass  # call release() to be sure changes are written and locks are released
8

Bạn có thể vượt qua tổ tiên cam kết bằng cách sắp xếp các cuộc gọi đến

new_branch = cloned_repo.create_head("feature")  # create a new branch ...
assert cloned_repo.active_branch != new_branch  # which wasn't checked out yet ...
self.assertEqual(new_branch.commit, cloned_repo.active_branch.commit)  # pointing to the checked-out commit
# It's easy to let a branch point to the previous commit, without affecting anything else
# Each reference provides access to the git object it points to, usually commits
assert new_branch.set_commit("HEAD~1").commit == cloned_repo.active_branch.commit.parents[0]
1

repo.config_reader()  # get a config reader for read-only access
with repo.config_writer():  # get a config writer to change configuration
    pass  # call release() to be sure changes are written and locks are released
9

Trên tương ứng với

new_branch = cloned_repo.create_head("feature")  # create a new branch ...
assert cloned_repo.active_branch != new_branch  # which wasn't checked out yet ...
self.assertEqual(new_branch.commit, cloned_repo.active_branch.commit)  # pointing to the checked-out commit
# It's easy to let a branch point to the previous commit, without affecting anything else
# Each reference provides access to the git object it points to, usually commits
assert new_branch.set_commit("HEAD~1").commit == cloned_repo.active_branch.commit.parents[0]
2 hoặc
new_branch = cloned_repo.create_head("feature")  # create a new branch ...
assert cloned_repo.active_branch != new_branch  # which wasn't checked out yet ...
self.assertEqual(new_branch.commit, cloned_repo.active_branch.commit)  # pointing to the checked-out commit
# It's easy to let a branch point to the previous commit, without affecting anything else
# Each reference provides access to the git object it points to, usually commits
assert new_branch.set_commit("HEAD~1").commit == cloned_repo.active_branch.commit.parents[0]
3 theo cách nói của Git.

Đối tượng cây

A

new_branch = cloned_repo.create_head("feature")  # create a new branch ...
assert cloned_repo.active_branch != new_branch  # which wasn't checked out yet ...
self.assertEqual(new_branch.commit, cloned_repo.active_branch.commit)  # pointing to the checked-out commit
# It's easy to let a branch point to the previous commit, without affecting anything else
# Each reference provides access to the git object it points to, usually commits
assert new_branch.set_commit("HEAD~1").commit == cloned_repo.active_branch.commit.parents[0]
4 ghi lại con trỏ vào nội dung của một thư mục. Hãy nói rằng bạn muốn cây gốc của cam kết mới nhất trên nhánh chính

assert not bare_repo.is_dirty()  # check the dirty state
repo.untracked_files  # retrieve a list of untracked files
# ['my_untracked_file']
0

Khi bạn có một cái cây, bạn có thể nhận được nội dung của nó

assert not bare_repo.is_dirty()  # check the dirty state
repo.untracked_files  # retrieve a list of untracked files
# ['my_untracked_file']
1

Thật hữu ích khi biết rằng một cây hoạt động giống như một danh sách với khả năng truy vấn các mục theo tên

assert not bare_repo.is_dirty()  # check the dirty state
repo.untracked_files  # retrieve a list of untracked files
# ['my_untracked_file']
2

Có một phương pháp tiện lợi cho phép bạn lấy một đối tượng phụ được đặt tên từ cây có cú pháp tương tự như cách các đường dẫn được viết trong hệ thống POSIX

assert not bare_repo.is_dirty()  # check the dirty state
repo.untracked_files  # retrieve a list of untracked files
# ['my_untracked_file']
3

Bạn cũng có thể nhận được một cây gốc cam kết trực tiếp từ kho lưu trữ

assert not bare_repo.is_dirty()  # check the dirty state
repo.untracked_files  # retrieve a list of untracked files
# ['my_untracked_file']
4

Vì cây chỉ cho phép truy cập trực tiếp vào các mục con trung gian của chúng, hãy sử dụng phương pháp Traverse để có được một trình lặp để truy xuất các mục

assert not bare_repo.is_dirty()  # check the dirty state
repo.untracked_files  # retrieve a list of untracked files
# ['my_untracked_file']
5

Ghi chú

Nếu cây trả lại các đối tượng mô hình con, chúng sẽ cho rằng chúng tồn tại tại cam kết đầu hiện tại. Cây nó có nguồn gốc từ có thể bắt nguồn từ một cam kết khác, mà nó không biết. Đó là lý do tại sao người gọi sẽ phải đặt mô hình con sở hữu hoặc cam kết cha mẹ bằng phương thức

new_branch = cloned_repo.create_head("feature")  # create a new branch ...
assert cloned_repo.active_branch != new_branch  # which wasn't checked out yet ...
self.assertEqual(new_branch.commit, cloned_repo.active_branch.commit)  # pointing to the checked-out commit
# It's easy to let a branch point to the previous commit, without affecting anything else
# Each reference provides access to the git object it points to, usually commits
assert new_branch.set_commit("HEAD~1").commit == cloned_repo.active_branch.commit.parents[0]
5.

Đối tượng chỉ mục

Chỉ số Git là giai đoạn chứa các thay đổi được viết bằng cam kết tiếp theo hoặc nơi cuối cùng hợp nhất phải diễn ra. Bạn có thể tự do truy cập và thao tác thông tin này bằng đối tượng

new_branch = cloned_repo.create_head("feature")  # create a new branch ...
assert cloned_repo.active_branch != new_branch  # which wasn't checked out yet ...
self.assertEqual(new_branch.commit, cloned_repo.active_branch.commit)  # pointing to the checked-out commit
# It's easy to let a branch point to the previous commit, without affecting anything else
# Each reference provides access to the git object it points to, usually commits
assert new_branch.set_commit("HEAD~1").commit == cloned_repo.active_branch.commit.parents[0]
6. Sửa đổi chỉ mục một cách dễ dàng

assert not bare_repo.is_dirty()  # check the dirty state
repo.untracked_files  # retrieve a list of untracked files
# ['my_untracked_file']
6

Tạo các chỉ số mới từ các cây khác hoặc là kết quả của việc hợp nhất. Viết kết quả đó vào một tệp chỉ mục mới để kiểm tra sau.

assert not bare_repo.is_dirty()  # check the dirty state
repo.untracked_files  # retrieve a list of untracked files
# ['my_untracked_file']
7

Xử lý điều khiển từ xa

assert os.path.isdir(cloned_repo.working_tree_dir)  # directory with your work files
assert cloned_repo.git_dir.startswith(cloned_repo.working_tree_dir)  # directory containing the git repository
assert bare_repo.working_tree_dir is None  # bare repositories have no working tree
2 được sử dụng làm bí danh cho kho lưu trữ nước ngoài để dễ dàng đẩy và lấy từ chúng

assert not bare_repo.is_dirty()  # check the dirty state
repo.untracked_files  # retrieve a list of untracked files
# ['my_untracked_file']
8

Bạn có thể dễ dàng truy cập thông tin cấu hình cho một từ xa bằng cách truy cập các tùy chọn như thể chúng là thuộc tính. Việc sửa đổi cấu hình từ xa là rõ ràng hơn mặc dù.

assert not bare_repo.is_dirty()  # check the dirty state
repo.untracked_files  # retrieve a list of untracked files
# ['my_untracked_file']
9

Bạn cũng có thể chỉ định các môi trường tùy chỉnh mỗi cuộc gọi bằng cách sử dụng Trình quản lý bối cảnh mới trên lệnh GIT, ví dụ: để sử dụng một khóa SSH cụ thể. Ví dụ sau đây hoạt động với GIT bắt đầu từ v2.3:

cloned_repo = repo.clone(os.path.join(rw_dir, "to/this/path"))
assert cloned_repo.__class__ is Repo  # clone an existing repository
assert Repo.init(os.path.join(rw_dir, "path/for/new/repo")).__class__ is Repo
0

Cái này đặt một tập lệnh tùy chỉnh sẽ được thực thi thay cho SSH và có thể được sử dụng trong GIT trước v2.3:

cloned_repo = repo.clone(os.path.join(rw_dir, "to/this/path"))
assert cloned_repo.__class__ is Repo  # clone an existing repository
assert Repo.init(os.path.join(rw_dir, "path/for/new/repo")).__class__ is Repo
1

Ở đây, một ví dụ có thể thực thi có thể được sử dụng thay cho SSH_Executable ở trên:

cloned_repo = repo.clone(os.path.join(rw_dir, "to/this/path"))
assert cloned_repo.__class__ is Repo  # clone an existing repository
assert Repo.init(os.path.join(rw_dir, "path/for/new/repo")).__class__ is Repo
2

Xin lưu ý rằng tập lệnh phải được thực thi (nghĩa là Chmod +x script.sh). StricthostKeyChecking = Không được sử dụng để tránh lời nhắc yêu cầu lưu khóa máy chủ vào ~/.ssh/respires_hosts, điều này xảy ra trong trường hợp bạn chạy điều này dưới dạng daemon.

Bạn cũng có thể có một cái nhìn về git.update_environment (Mạnh) trong trường hợp bạn muốn thiết lập một môi trường thay đổi vĩnh viễn hơn.

Xử lý mô hình con

assert os.path.isdir(cloned_repo.working_tree_dir)  # directory with your work files
assert cloned_repo.git_dir.startswith(cloned_repo.working_tree_dir)  # directory containing the git repository
assert bare_repo.working_tree_dir is None  # bare repositories have no working tree
5 có thể được xử lý thuận tiện bằng các phương pháp do Gitpython cung cấp và như một lợi ích bổ sung, Gitpython cung cấp chức năng hoạt động thông minh hơn và ít lỗi hơn so với việc triển khai C-git ban đầu của nó hoặc điều chỉnh cấu hình hiện có.

cloned_repo = repo.clone(os.path.join(rw_dir, "to/this/path"))
assert cloned_repo.__class__ is Repo  # clone an existing repository
assert Repo.init(os.path.join(rw_dir, "path/for/new/repo")).__class__ is Repo
3

Ngoài chức năng truy vấn, bạn có thể chuyển kho lưu trữ mô hình con sang một đường dẫn khác, viết cấu hình của nó, cập nhật cây làm việc của nó và xóa hoặc thêm chúng.

Nếu bạn có được đối tượng mô hình con của mình bằng cách đi qua một đối tượng cây không bắt nguồn từ cam kết đầu, bạn phải thông báo cho mô hình con về cam kết thực tế của nó để lấy dữ liệu từ bằng cách sử dụng phương thức

past = cloned_repo.create_tag(
    "past",
    ref=new_branch,
    message="This is a tag-object pointing to %s" % new_branch.name,
)
self.assertEqual(past.commit, new_branch.commit)  # the tag points to the specified commit
assert past.tag.message.startswith("This is")  # and its object carries the message provided

now = cloned_repo.create_tag("now")  # This is a tag-reference. It may not carry meta-data
assert now.tag is None
4.

Loại

past = cloned_repo.create_tag(
    "past",
    ref=new_branch,
    message="This is a tag-object pointing to %s" % new_branch.name,
)
self.assertEqual(past.commit, new_branch.commit)  # the tag points to the specified commit
assert past.tag.message.startswith("This is")  # and its object carries the message provided

now = cloned_repo.create_tag("now")  # This is a tag-reference. It may not carry meta-data
assert now.tag is None
5 đặc biệt cho phép bạn coi kho lưu trữ chính của mình là gốc của một hệ thống phân cấp các mô hình con, cho phép xử lý mô hình con rất thuận tiện. Phương pháp
past = cloned_repo.create_tag(
    "past",
    ref=new_branch,
    message="This is a tag-object pointing to %s" % new_branch.name,
)
self.assertEqual(past.commit, new_branch.commit)  # the tag points to the specified commit
assert past.tag.message.startswith("This is")  # and its object carries the message provided

now = cloned_repo.create_tag("now")  # This is a tag-reference. It may not carry meta-data
assert now.tag is None
1 của nó được thực hiện lại để cung cấp một cách nâng cao để cập nhật các mô hình con khi chúng thay đổi giá trị của chúng theo thời gian. Phương thức cập nhật sẽ theo dõi các thay đổi và đảm bảo rằng kiểm tra cây và mô hình phụ của bạn vẫn ổn định, điều này rất hữu ích trong trường hợp các mô hình con bị xóa hoặc thêm vào tên chỉ hai trong số các trường hợp được xử lý.

Ngoài ra, Gitpython thêm chức năng để theo dõi một nhánh cụ thể, thay vì chỉ là một cam kết. Được hỗ trợ bởi các phương thức cập nhật tùy chỉnh, bạn có thể tự động cập nhật các mô hình con lên bản sửa đổi mới nhất có sẵn trong kho lưu trữ từ xa, cũng như để theo dõi các thay đổi và chuyển động của các mô hình con này. Để sử dụng nó, đặt tên của nhánh bạn muốn theo dõi tùy chọn

past = cloned_repo.create_tag(
    "past",
    ref=new_branch,
    message="This is a tag-object pointing to %s" % new_branch.name,
)
self.assertEqual(past.commit, new_branch.commit)  # the tag points to the specified commit
assert past.tag.message.startswith("This is")  # and its object carries the message provided

now = cloned_repo.create_tag("now")  # This is a tag-reference. It may not carry meta-data
assert now.tag is None
7 của tệp .gitmodules và sử dụng các phương thức cập nhật Gitpython trên kho lưu trữ kết quả với tham số
past = cloned_repo.create_tag(
    "past",
    ref=new_branch,
    message="This is a tag-object pointing to %s" % new_branch.name,
)
self.assertEqual(past.commit, new_branch.commit)  # the tag points to the specified commit
assert past.tag.message.startswith("This is")  # and its object carries the message provided

now = cloned_repo.create_tag("now")  # This is a tag-reference. It may not carry meta-data
assert now.tag is None
8 được bật. Trong trường hợp sau, SHA của mô hình con của bạn sẽ bị bỏ qua, thay vào đó, một nhánh theo dõi cục bộ sẽ được cập nhật lên nhánh từ xa tương ứng, miễn là không có thay đổi cục bộ. Hành vi kết quả giống như một trong những SVN :: bên ngoài, có thể hữu ích trong thời gian.

Có được thông tin khác

Khác biệt thường có thể thu được bằng các lớp con của

past = cloned_repo.create_tag(
    "past",
    ref=new_branch,
    message="This is a tag-object pointing to %s" % new_branch.name,
)
self.assertEqual(past.commit, new_branch.commit)  # the tag points to the specified commit
assert past.tag.message.startswith("This is")  # and its object carries the message provided

now = cloned_repo.create_tag("now")  # This is a tag-reference. It may not carry meta-data
assert now.tag is None
9 vì chúng cung cấp phương pháp
bare_repo = Repo.init(os.path.join(rw_dir, "bare-repo"), bare=True)
assert bare_repo.bare
00. Hoạt động này mang lại một
bare_repo = Repo.init(os.path.join(rw_dir, "bare-repo"), bare=True)
assert bare_repo.bare
01 cho phép bạn dễ dàng truy cập thông tin khác biệt về các đường dẫn.

Khác biệt có thể được thực hiện giữa chỉ số và cây, chỉ số và cây làm việc, cây và cây cũng như cây và bản sao làm việc. Nếu cam kết có liên quan, cây của họ sẽ được sử dụng ngầm.

cloned_repo = repo.clone(os.path.join(rw_dir, "to/this/path"))
assert cloned_repo.__class__ is Repo  # clone an existing repository
assert Repo.init(os.path.join(rw_dir, "path/for/new/repo")).__class__ is Repo
4

Mục được trả về là một Diffindex về cơ bản là danh sách các đối tượng khác. Nó cung cấp thêm lọc để dễ dàng tìm thấy những gì bạn có thể đang tìm kiếm.

cloned_repo = repo.clone(os.path.join(rw_dir, "to/this/path"))
assert cloned_repo.__class__ is Repo  # clone an existing repository
assert Repo.init(os.path.join(rw_dir, "path/for/new/repo")).__class__ is Repo
5

Sử dụng Khung Diff nếu bạn muốn triển khai chức năng Git-Status.

  • Một sự khác biệt giữa chỉ mục và cây cam kết mà đầu của bạn chỉ ra

  • Sử dụng
    bare_repo = Repo.init(os.path.join(rw_dir, "bare-repo"), bare=True)
    assert bare_repo.bare
    
    02

  • Một sự khác biệt giữa chỉ số và cây làm việc

  • Sử dụng
    bare_repo = Repo.init(os.path.join(rw_dir, "bare-repo"), bare=True)
    assert bare_repo.bare
    
    03

  • Một danh sách các tệp chưa được truy cập

  • Sử dụng
    bare_repo = Repo.init(os.path.join(rw_dir, "bare-repo"), bare=True)
    assert bare_repo.bare
    
    04

Chuyển đổi nhánh

Để chuyển đổi giữa các nhánh tương tự như

bare_repo = Repo.init(os.path.join(rw_dir, "bare-repo"), bare=True)
assert bare_repo.bare
05, bạn thực sự cần chỉ ra tham chiếu tượng trưng đầu của mình vào nhánh mới và đặt lại chỉ mục và bản sao làm việc để khớp. Một cách thủ công đơn giản để làm điều đó là cách sau

cloned_repo = repo.clone(os.path.join(rw_dir, "to/this/path"))
assert cloned_repo.__class__ is Repo  # clone an existing repository
assert Repo.init(os.path.join(rw_dir, "path/for/new/repo")).__class__ is Repo
6

Cách tiếp cận trước đây sẽ ghi đè một cách dã man các thay đổi của người dùng trong bản sao và chỉ mục làm việc và ít tinh vi hơn so với

bare_repo = Repo.init(os.path.join(rw_dir, "bare-repo"), bare=True)
assert bare_repo.bare
06. Cái sau thường sẽ ngăn bạn phá hủy công việc của bạn. Sử dụng cách tiếp cận an toàn hơn như sau.

cloned_repo = repo.clone(os.path.join(rw_dir, "to/this/path"))
assert cloned_repo.__class__ is Repo  # clone an existing repository
assert Repo.init(os.path.join(rw_dir, "path/for/new/repo")).__class__ is Repo
7

Khởi tạo kho lưu trữ

Trong ví dụ này, chúng tôi sẽ khởi tạo một kho lưu trữ trống, thêm một tệp trống vào chỉ mục và thực hiện thay đổi.

cloned_repo = repo.clone(os.path.join(rw_dir, "to/this/path"))
assert cloned_repo.__class__ is Repo  # clone an existing repository
assert Repo.init(os.path.join(rw_dir, "path/for/new/repo")).__class__ is Repo
8

Xin hãy xem các phương pháp riêng lẻ vì chúng thường hỗ trợ một lượng lớn các đối số để tùy chỉnh hành vi của họ.

Sử dụng Git trực tiếp

Trong trường hợp bạn thiếu chức năng vì nó chưa được gói, bạn có thể sử dụng trực tiếp lệnh

bare_repo = Repo.init(os.path.join(rw_dir, "bare-repo"), bare=True)
assert bare_repo.bare
07 một cách thuận tiện. Nó được sở hữu bởi mỗi ví dụ kho lưu trữ.

cloned_repo = repo.clone(os.path.join(rw_dir, "to/this/path"))
assert cloned_repo.__class__ is Repo  # clone an existing repository
assert Repo.init(os.path.join(rw_dir, "path/for/new/repo")).__class__ is Repo
9

Giá trị trả về theo mặc định sẽ là một chuỗi của kênh đầu ra tiêu chuẩn được tạo bởi lệnh.

Các đối số từ khóa dịch sang các đối số từ khóa ngắn và dài trên dòng lệnh. Khái niệm đặc biệt

bare_repo = Repo.init(os.path.join(rw_dir, "bare-repo"), bare=True)
assert bare_repo.bare
08 sẽ tạo một lá cờ mà không có giá trị như
bare_repo = Repo.init(os.path.join(rw_dir, "bare-repo"), bare=True)
assert bare_repo.bare
09.

Nếu

bare_repo = Repo.init(os.path.join(rw_dir, "bare-repo"), bare=True)
assert bare_repo.bare
10 được tìm thấy trong các đối số, nó sẽ được giảm âm thầm. Danh sách và bộ dữ liệu được thông qua như các đối số sẽ được giải nén đệ quy cho các đối số riêng lẻ. Các đối tượng được chuyển đổi thành các chuỗi bằng hàm
bare_repo = Repo.init(os.path.join(rw_dir, "bare-repo"), bare=True)
assert bare_repo.bare
11.

Cơ sở dữ liệu đối tượng

Các phiên bản

with open(os.path.join(rw_dir, "repo.tar"), "wb") as fp:
    repo.archive(fp)
3 được cung cấp bởi thể hiện cơ sở dữ liệu đối tượng của nó sẽ được sử dụng khi trích xuất bất kỳ dữ liệu nào hoặc khi viết các đối tượng mới.

Loại cơ sở dữ liệu xác định các đặc điểm hiệu suất nhất định, chẳng hạn như số lượng đối tượng có thể đọc mỗi giây, việc sử dụng tài nguyên khi đọc các tệp dữ liệu lớn, cũng như dấu chân bộ nhớ trung bình của ứng dụng của bạn.

Gitdb¶

GitDB là một triển khai Pure-Python của cơ sở dữ liệu đối tượng Git. Đây là cơ sở dữ liệu mặc định để sử dụng trong Gitpython 0.3. Nó sử dụng ít bộ nhớ hơn khi xử lý các tệp lớn, nhưng sẽ chậm hơn 2 đến 5 lần khi trích xuất số lượng lớn các đối tượng nhỏ từ các kho lưu trữ dày đặc:

with open(os.path.join(rw_dir, "repo.tar"), "wb") as fp:
    repo.archive(fp)
0

Gitcmdobjectdb¶

Cơ sở dữ liệu lệnh Git sử dụng các phiên bản tệp git-cat liên tục để đọc thông tin kho lưu trữ. Chúng hoạt động rất nhanh trong mọi điều kiện, nhưng sẽ tiêu thụ thêm bộ nhớ cho chính quy trình. Khi trích xuất các tệp lớn, việc sử dụng bộ nhớ sẽ cao hơn nhiều so với

bare_repo = Repo.init(os.path.join(rw_dir, "bare-repo"), bare=True)
assert bare_repo.bare
13:

with open(os.path.join(rw_dir, "repo.tar"), "wb") as fp:
    repo.archive(fp)
1

Git Lệnh gỡ lỗi và Tùy chỉnh Or

Sử dụng các biến môi trường, bạn có thể điều chỉnh thêm hành vi của lệnh GIT.

  • GIT_PYTHON_TRACE

  • Nếu được đặt thành không 0, tất cả các lệnh git được thực thi sẽ được hiển thị khi chúng xảy ra
  • Nếu được đặt thành đầy đủ, lệnh git đã thực hiện _and_ toàn bộ đầu ra của nó trên stdout và stderr sẽ được hiển thị khi chúng xảy ra

Lưu ý: Tất cả việc ghi nhật ký được xuất ra bằng cách sử dụng bộ ghi Python, vì vậy hãy đảm bảo chương trình của bạn được cấu hình để hiển thị các tin nhắn cấp thông tin. Nếu đây không phải là trường hợp, hãy thử thêm phần sau vào chương trình của bạn:: All logging is outputted using a Python logger, so make sure your program is configured to show INFO-level messages. If this is not the case, try adding the following to your program:

with open(os.path.join(rw_dir, "repo.tar"), "wb") as fp:
    repo.archive(fp)
2

  • GIT_PYTHON_GIT_EXECUTABLE

  • Nếu được đặt, nó phải chứa đường dẫn đầy đủ đến thực thi Git, ví dụ: C: \ Tệp chương trình (x86) \ git \ bin \ git.exe trên Windows hoặc/usr/bin/git trên Linux.

Va thậm chi nhiêu hơn …¶

Có nhiều chức năng hơn trong đó, như khả năng lưu trữ kho lưu trữ, nhận số liệu thống kê và nhật ký, đổ lỗi và có lẽ một vài điều khác không được đề cập ở đây.

Kiểm tra các bài kiểm tra đơn vị để được giới thiệu chuyên sâu về cách sử dụng mỗi chức năng được sử dụng.