Python cơ bản github

Bạn đã bao giờ làm việc với một dự án Python đã ngừng hoạt động sau khi bạn thực hiện thay đổi ở đây hoặc dọn dẹp PEP-8 ở đó và bạn không chắc chắn làm thế nào để lấy lại dự án đó chưa? . Git là một trong những hệ thống kiểm soát phiên bản phổ biến nhất hiện nay

Trong hướng dẫn này, tôi sẽ hướng dẫn bạn Git là gì, cách sử dụng nó cho các dự án cá nhân của bạn và cách sử dụng nó cùng với GitHub để làm việc với những người khác trong các dự án lớn hơn. Chúng ta sẽ xem cách tạo repo, cách thêm cả tệp mới và tệp đã sửa đổi cũng như cách điều hướng qua lịch sử dự án của bạn để bạn có thể “quay lại” thời điểm dự án của bạn đang hoạt động

Bài viết này giả định rằng bạn đã cài đặt Git trên hệ thống của mình. Nếu không, cuốn sách Pro Git tuyệt vời có một phần về cách thực hiện điều đó

Git là gì?

Git là một hệ thống kiểm soát phiên bản phân tán [DVCS]. Hãy chia nhỏ điều đó ra một chút và xem ý nghĩa của nó

Loại bỏ các quảng cáo

Kiểm soát phiên bản

Hệ thống kiểm soát phiên bản [VCS] là một bộ công cụ theo dõi lịch sử của một tập hợp tệp. Điều này có nghĩa là bạn có thể yêu cầu VCS của mình [Git, trong trường hợp của chúng tôi] lưu trạng thái các tệp của bạn bất kỳ lúc nào. Sau đó, bạn có thể tiếp tục chỉnh sửa các tệp và lưu trữ trạng thái đó. Lưu trạng thái tương tự như tạo bản sao lưu thư mục làm việc của bạn. Khi sử dụng Git, chúng tôi coi việc lưu trạng thái này là thực hiện một cam kết

Khi bạn thực hiện một cam kết trong Git, bạn thêm một thông báo cam kết giải thích ở cấp độ cao những thay đổi bạn đã thực hiện trong cam kết này. Git có thể hiển thị cho bạn lịch sử của tất cả các cam kết và thông báo cam kết của chúng. Điều này cung cấp một lịch sử hữu ích về những công việc bạn đã làm và thực sự có thể giúp xác định chính xác thời điểm một lỗi xâm nhập vào hệ thống

Ngoài việc hiển thị cho bạn nhật ký các thay đổi bạn đã thực hiện, Git còn cho phép bạn so sánh các tệp giữa các lần xác nhận khác nhau. Như tôi đã đề cập trước đó, Git cũng sẽ cho phép bạn trả lại bất kỳ tệp nào [hoặc tất cả các tệp] về một cam kết trước đó mà không tốn nhiều công sức

Kiểm soát phiên bản phân tán

OK, vậy đó là một hệ thống kiểm soát phiên bản. Phần được phân phối là gì? . Các hệ thống kiểm soát phiên bản đầu hoạt động bằng cách lưu trữ cục bộ tất cả các cam kết đó trên ổ cứng của bạn. Bộ sưu tập các xác nhận này được gọi là kho lưu trữ. Điều này đã giải quyết được vấn đề “Tôi cần quay lại vị trí ban đầu” nhưng không mở rộng quy mô tốt cho một nhóm làm việc trên cùng một cơ sở mã

Khi các nhóm lớn hơn bắt đầu hoạt động [và mạng trở nên phổ biến hơn], các VCS đã thay đổi để lưu trữ kho lưu trữ trên một máy chủ trung tâm được chia sẻ bởi nhiều nhà phát triển. Mặc dù điều này giải quyết được nhiều vấn đề, nhưng nó cũng tạo ra những vấn đề mới, chẳng hạn như khóa tệp

Tiếp bước một vài sản phẩm khác, Git đã đoạn tuyệt với mô hình đó. Git không có máy chủ trung tâm có phiên bản cuối cùng của kho lưu trữ. Tất cả người dùng có một bản sao đầy đủ của kho lưu trữ. Điều này có nghĩa là việc đưa tất cả các nhà phát triển trở lại cùng một trang đôi khi có thể khó khăn, nhưng điều đó cũng có nghĩa là các nhà phát triển có thể làm việc ngoại tuyến hầu hết thời gian, chỉ kết nối với các kho lưu trữ khác khi họ cần chia sẻ công việc của mình

Lúc đầu, đoạn cuối có vẻ hơi khó hiểu vì có rất nhiều nhà phát triển sử dụng GitHub làm kho lưu trữ trung tâm mà mọi người phải lấy từ đó. Điều này đúng, nhưng Git không áp đặt điều này. Trong một số trường hợp, thật thuận tiện khi có một vị trí trung tâm để chia sẻ mã. Kho lưu trữ đầy đủ vẫn được lưu trữ trên tất cả các kho lưu trữ cục bộ ngay cả khi bạn sử dụng GitHub

Sử dụng cơ bản

Bây giờ chúng ta đã nói về Git nói chung, hãy xem qua một ví dụ và xem nó hoạt động như thế nào. Chúng tôi sẽ bắt đầu bằng cách làm việc với Git chỉ trên máy cục bộ của chúng tôi. Khi chúng tôi hiểu rõ về điều đó, chúng tôi sẽ thêm GitHub và giải thích cách bạn có thể tương tác với nó

Tạo một Repo mới

Để làm việc với Git, trước tiên bạn cần cho nó biết bạn là ai. Bạn có thể đặt tên người dùng của mình bằng lệnh

# hello.py
print['hello Git!']
5

$ git config --global user.name "your name goes here"

Khi đã được thiết lập, bạn sẽ cần một repo để hoạt động. Tạo một repo rất đơn giản. Sử dụng lệnh

# hello.py
print['hello Git!']
6 trong một thư mục

$ mkdir example
$ cd example
$ git init
Initialized empty Git repository in /home/jima/tmp/example/.git/

Khi bạn có repo, bạn có thể hỏi Git về nó. Lệnh Git mà bạn sẽ sử dụng thường xuyên nhất là

# hello.py
print['hello Git!']
7. Hãy thử điều đó ngay bây giờ

$ git status
On branch master

Initial commit

nothing to commit [create/copy files and use "git add" to track]

Điều này cho bạn thấy một vài thông tin. bạn đang ở chi nhánh nào,

# hello.py
print['hello Git!']
8 [chúng ta sẽ nói về chi nhánh sau] và rằng bạn không có gì để cam kết. Phần cuối cùng này có nghĩa là không có tệp nào trong thư mục này mà Git không biết. Tốt quá, vì chúng ta vừa tạo thư mục

Thêm một tệp mới

Bây giờ hãy tạo một tệp mà Git không biết. Với trình soạn thảo yêu thích của bạn, hãy tạo tệp

# hello.py
print['hello Git!']
9, tệp này chỉ chứa một câu lệnh in trong đó

# hello.py
print['hello Git!']

Nếu bạn chạy lại

# hello.py
print['hello Git!']
7, bạn sẽ thấy một kết quả khác

$ git status
On branch master

Initial commit

Untracked files:
  [use "git add ..." to include in what will be committed]

   hello.py

nothing added to commit but untracked files present [use "git add" to track]

Bây giờ Git nhìn thấy tệp mới và cho bạn biết rằng nó không bị theo dõi. Đó chỉ là cách nói của Git rằng tệp không phải là một phần của repo và không nằm dưới sự kiểm soát của phiên bản. Chúng tôi có thể khắc phục điều đó bằng cách thêm tệp vào Git. Sử dụng lệnh

$ git status
On branch master

Initial commit

Untracked files:
  [use "git add ..." to include in what will be committed]

   hello.py

nothing added to commit but untracked files present [use "git add" to track]
1 để thực hiện điều đó

$ git add hello.py
$ git status
On branch master

Initial commit

Changes to be committed:
  [use "git rm --cached ..." to unstage]

   new file:   hello.py

Bây giờ Git biết về

# hello.py
print['hello Git!']
9 và liệt kê nó dưới những thay đổi được cam kết. Việc thêm tệp vào Git sẽ di chuyển tệp vào khu vực tổ chức [được thảo luận bên dưới] và có nghĩa là chúng tôi có thể chuyển tệp đó vào repo

Loại bỏ các quảng cáo

Cam kết thay đổi

Khi bạn thực hiện các thay đổi, bạn đang yêu cầu Git tạo ảnh chụp nhanh trạng thái này trong repo. Làm điều đó ngay bây giờ bằng cách sử dụng lệnh

$ git status
On branch master

Initial commit

Untracked files:
  [use "git add ..." to include in what will be committed]

   hello.py

nothing added to commit but untracked files present [use "git add" to track]
3. Tùy chọn
$ git status
On branch master

Initial commit

Untracked files:
  [use "git add ..." to include in what will be committed]

   hello.py

nothing added to commit but untracked files present [use "git add" to track]
4 yêu cầu Git sử dụng thông báo cam kết theo sau. Nếu bạn không sử dụng
$ git status
On branch master

Initial commit

Untracked files:
  [use "git add ..." to include in what will be committed]

   hello.py

nothing added to commit but untracked files present [use "git add" to track]
4, Git sẽ hiển thị trình chỉnh sửa để bạn tạo thông báo cam kết. Nói chung, bạn muốn thông báo cam kết của mình phản ánh những gì đã thay đổi trong cam kết

$ git commit -m "creating hello.py"
[master [root-commit] 25b09b9] creating hello.py
 1 file changed, 3 insertions[+]
 create mode 100755 hello.py

$ git status
On branch master
nothing to commit, working directory clean

Bạn có thể thấy rằng lệnh cam kết đã trả về một loạt thông tin, hầu hết trong số đó không hữu ích, nhưng nó cho bạn biết rằng chỉ có 1 tệp được thay đổi [điều này có nghĩa là chúng tôi đã thêm một tệp]. Nó cũng cho bạn biết SHA của cam kết [

$ git status
On branch master

Initial commit

Untracked files:
  [use "git add ..." to include in what will be committed]

   hello.py

nothing added to commit but untracked files present [use "git add" to track]
6]. Chúng ta sẽ nói về SHA một chút sau

Chạy lại lệnh

# hello.py
print['hello Git!']
7 cho thấy rằng chúng ta có một thư mục hoạt động sạch sẽ, nghĩa là tất cả các thay đổi đều được cam kết với Git

Tại thời điểm này, chúng ta cần dừng hướng dẫn của mình và trò chuyện nhanh về khu vực tổ chức

Qua một bên. khu vực tổ chức

Không giống như nhiều hệ thống kiểm soát phiên bản, Git có khu vực tổ chức [thường được gọi là chỉ mục]. Khu vực tổ chức là cách Git theo dõi những thay đổi mà bạn muốn thực hiện trong lần cam kết tiếp theo. Khi chúng tôi chạy

$ git status
On branch master

Initial commit

Untracked files:
  [use "git add ..." to include in what will be committed]

   hello.py

nothing added to commit but untracked files present [use "git add" to track]
1 ở trên, chúng tôi đã nói với Git rằng chúng tôi muốn chuyển tệp mới
# hello.py
print['hello Git!']
9 sang khu vực tổ chức. Sự thay đổi này được phản ánh trong
# hello.py
print['hello Git!']
7. Tệp đã chuyển từ phần không được theo dõi sang phần được cam kết của đầu ra

Lưu ý rằng khu vực tổ chức phản ánh chính xác nội dung của tệp khi bạn chạy

$ git status
On branch master

Initial commit

Untracked files:
  [use "git add ..." to include in what will be committed]

   hello.py

nothing added to commit but untracked files present [use "git add" to track]
1. Nếu bạn sửa đổi nó một lần nữa, tệp sẽ xuất hiện ở cả phần có giai đoạn và phần không có giai đoạn của đầu ra trạng thái

Tại bất kỳ thời điểm nào làm việc với một tệp trong Git [giả sử nó đã được cam kết một lần], có thể có ba phiên bản tệp mà bạn có thể làm việc với

  • phiên bản trên ổ cứng mà bạn đang chỉnh sửa
  • một phiên bản khác mà Git đã lưu trữ trong khu vực tổ chức của bạn
  • phiên bản mới nhất đã đăng ký vào repo

Cả ba trong số này có thể là các phiên bản khác nhau của tệp. Di chuyển các thay đổi sang khu vực tổ chức và sau đó cam kết chúng sẽ đưa tất cả các phiên bản này trở lại đồng bộ hóa

Khi bắt đầu với Git, tôi thấy staging area hơi khó hiểu và hơi khó chịu. Nó dường như thêm các bước bổ sung vào quy trình mà không thêm bất kỳ lợi ích nào. Khi bạn lần đầu tiên học Git, điều đó thực sự đúng. Sau một thời gian, sẽ có những tình huống mà bạn thực sự đánh giá cao chức năng đó. Thật không may, những tình huống đó nằm ngoài phạm vi của hướng dẫn này

Nếu bạn quan tâm đến thông tin chi tiết hơn về khu vực tổ chức, tôi có thể đề xuất bài đăng trên blog này

$ git add hello.py
$ git status
On branch master

Initial commit

Changes to be committed:
  [use "git rm --cached ..." to unstage]

   new file:   hello.py
2

Lệnh trạng thái rất tiện dụng và bạn sẽ thấy mình sử dụng nó thường xuyên. Nhưng đôi khi bạn sẽ thấy rằng có rất nhiều tệp hiển thị trong phần không được theo dõi và bạn muốn Git không nhìn thấy. Đó là nơi mà tệp

$ git add hello.py
$ git status
On branch master

Initial commit

Changes to be committed:
  [use "git rm --cached ..." to unstage]

   new file:   hello.py
2 xuất hiện

Hãy xem qua một ví dụ. Tạo một tệp Python mới trong cùng thư mục có tên là

$ git add hello.py
$ git status
On branch master

Initial commit

Changes to be committed:
  [use "git rm --cached ..." to unstage]

   new file:   hello.py
4

# myname.py
def get_name[]:
    return "Jim"

Sau đó sửa đổi lời chào của bạn. py bao gồm

$ git add hello.py
$ git status
On branch master

Initial commit

Changes to be committed:
  [use "git rm --cached ..." to unstage]

   new file:   hello.py
5 và gọi chức năng của nó

# hello.py
import myname

name = myname.get_name[]
print["hello {}".format[name]]

Khi bạn nhập một mô-đun cục bộ, Python sẽ biên dịch nó thành mã byte cho bạn và để tệp đó trên hệ thống tệp của bạn. Trong Python 2, nó sẽ để lại một tệp có tên

$ git add hello.py
$ git status
On branch master

Initial commit

Changes to be committed:
  [use "git rm --cached ..." to unstage]

   new file:   hello.py
6, nhưng chúng tôi sẽ cho rằng bạn đang chạy Python 3. Trong trường hợp đó, nó sẽ tạo một thư mục
$ git add hello.py
$ git status
On branch master

Initial commit

Changes to be committed:
  [use "git rm --cached ..." to unstage]

   new file:   hello.py
7 và lưu trữ tệp pyc ở đó. Đó là những gì được hiển thị bên dưới

$ ls
hello.py  myname.py
$ ./hello.py
hello Jim!
$ ls
hello.py  myname.py  __pycache__

Bây giờ nếu bạn chạy

# hello.py
print['hello Git!']
7, bạn sẽ thấy thư mục đó trong phần không được theo dõi. Cũng xin lưu ý rằng tệp
$ git add hello.py
$ git status
On branch master

Initial commit

Changes to be committed:
  [use "git rm --cached ..." to unstage]

   new file:   hello.py
4 mới của bạn không được theo dõi, trong khi những thay đổi bạn đã thực hiện đối với
# hello.py
print['hello Git!']
9 nằm trong một phần mới có tên là “Thay đổi không được sắp xếp cho cam kết”. Điều này chỉ có nghĩa là những thay đổi đó chưa được thêm vào khu vực tổ chức. Hãy thử nó ra

$ mkdir example
$ cd example
$ git init
Initialized empty Git repository in /home/jima/tmp/example/.git/
0

Trước khi chúng tôi chuyển sang tệp gitignore, hãy dọn dẹp mớ hỗn độn mà chúng tôi đã tạo ra một chút. Trước tiên, chúng tôi sẽ thêm các tệp

$ git add hello.py
$ git status
On branch master

Initial commit

Changes to be committed:
  [use "git rm --cached ..." to unstage]

   new file:   hello.py
4 và
# hello.py
print['hello Git!']
9, giống như chúng tôi đã làm trước đó

$ mkdir example
$ cd example
$ git init
Initialized empty Git repository in /home/jima/tmp/example/.git/
1

Hãy cam kết những thay đổi đó và hoàn thành việc dọn dẹp của chúng tôi

$ mkdir example
$ cd example
$ git init
Initialized empty Git repository in /home/jima/tmp/example/.git/
2

Bây giờ khi chạy status, tất cả những gì chúng ta thấy là thư mục

$ git add hello.py
$ git status
On branch master

Initial commit

Changes to be committed:
  [use "git rm --cached ..." to unstage]

   new file:   hello.py
7

$ mkdir example
$ cd example
$ git init
Initialized empty Git repository in /home/jima/tmp/example/.git/
3

Để bỏ qua tất cả các thư mục

$ git add hello.py
$ git status
On branch master

Initial commit

Changes to be committed:
  [use "git rm --cached ..." to unstage]

   new file:   hello.py
7 [và nội dung của chúng], chúng tôi sẽ thêm một tệp
$ git add hello.py
$ git status
On branch master

Initial commit

Changes to be committed:
  [use "git rm --cached ..." to unstage]

   new file:   hello.py
2 vào kho lưu trữ của chúng tôi. Điều này đơn giản như nó nghe. Sửa file [nhớ dấu chấm trước tên. ] trong trình chỉnh sửa yêu thích của bạn

$ mkdir example
$ cd example
$ git init
Initialized empty Git repository in /home/jima/tmp/example/.git/
4

Bây giờ khi chúng ta chạy

# hello.py
print['hello Git!']
7, chúng ta không còn thấy thư mục
$ git add hello.py
$ git status
On branch master

Initial commit

Changes to be committed:
  [use "git rm --cached ..." to unstage]

   new file:   hello.py
7 nữa. Tuy nhiên, chúng tôi thấy
$ git add hello.py
$ git status
On branch master

Initial commit

Changes to be committed:
  [use "git rm --cached ..." to unstage]

   new file:   hello.py
2 mới. Hãy xem

$ mkdir example
$ cd example
$ git init
Initialized empty Git repository in /home/jima/tmp/example/.git/
5

Tệp đó chỉ là một tệp văn bản thông thường và có thể được thêm vào repo của bạn như bất kỳ tệp nào khác. Làm điều đó ngay bây giờ

$ mkdir example
$ cd example
$ git init
Initialized empty Git repository in /home/jima/tmp/example/.git/
6

Một mục phổ biến khác trong tệp

$ git add hello.py
$ git status
On branch master

Initial commit

Changes to be committed:
  [use "git rm --cached ..." to unstage]

   new file:   hello.py
2 là thư mục bạn lưu trữ môi trường ảo của mình trong đó. Bạn có thể tìm hiểu thêm về virtualenv tại đây, nhưng thư mục virtualenv thường được gọi là
# myname.py
def get_name[]:
    return "Jim"
0 hoặc
# myname.py
def get_name[]:
    return "Jim"
1. Bạn có thể thêm những thứ này vào tệp
$ git add hello.py
$ git status
On branch master

Initial commit

Changes to be committed:
  [use "git rm --cached ..." to unstage]

   new file:   hello.py
2 của mình. Nếu có các tệp hoặc thư mục, chúng sẽ bị bỏ qua. Nếu họ không, thì sẽ không có gì xảy ra

Cũng có thể có một tệp

$ git add hello.py
$ git status
On branch master

Initial commit

Changes to be committed:
  [use "git rm --cached ..." to unstage]

   new file:   hello.py
2 toàn cầu được lưu trữ trong thư mục chính của bạn. Điều này rất hữu ích nếu trình soạn thảo của bạn muốn để các tệp tạm thời hoặc tệp sao lưu trong thư mục cục bộ

Đây là một ví dụ về tệp Python

$ git add hello.py
$ git status
On branch master

Initial commit

Changes to be committed:
  [use "git rm --cached ..." to unstage]

   new file:   hello.py
2 đơn giản

$ mkdir example
$ cd example
$ git init
Initialized empty Git repository in /home/jima/tmp/example/.git/
7

Để biết ví dụ đầy đủ hơn, hãy xem tại đây hoặc nếu bạn muốn xây dựng ví dụ của riêng mình,

# myname.py
def get_name[]:
    return "Jim"
5 sẽ cung cấp tất cả thông tin chi tiết bạn cần

Loại bỏ các quảng cáo

Những gì KHÔNG nên thêm vào Git Repo

Khi bạn lần đầu tiên bắt đầu làm việc với bất kỳ công cụ kiểm soát phiên bản nào, đặc biệt là Git, bạn có thể muốn đưa mọi thứ vào repo. Đây thường là một sai lầm. Có những hạn chế đối với Git cũng như những lo ngại về bảo mật buộc bạn phải giới hạn loại thông tin nào bạn thêm vào repo

Hãy bắt đầu với quy tắc ngón tay cái cơ bản về tất cả các hệ thống kiểm soát phiên bản

Chỉ đặt các tệp nguồn vào kiểm soát phiên bản, không bao giờ tạo tệp

Trong ngữ cảnh này, tệp nguồn là bất kỳ tệp nào bạn tạo, thường bằng cách nhập vào trình chỉnh sửa. Tệp được tạo là thứ mà máy tính tạo ra, thường bằng cách xử lý tệp nguồn. Ví dụ:

# hello.py
print['hello Git!']
9 là tệp nguồn, trong khi
# myname.py
def get_name[]:
    return "Jim"
7 sẽ là tệp được tạo

Có hai lý do để không bao gồm các tệp được tạo trong repo. Đầu tiên là làm như vậy là lãng phí thời gian và không gian. Các tệp đã tạo có thể được tạo lại bất cứ lúc nào và có thể cần được tạo ở dạng khác. Nếu ai đó đang sử dụng Jython hoặc IronPython trong khi bạn đang sử dụng trình thông dịch Cython, các tệp

# myname.py
def get_name[]:
    return "Jim"
8 có thể khá khác. Cam kết một hương vị cụ thể của tệp có thể gây ra xung đột

Lý do thứ hai để không lưu trữ các tệp đã tạo là các tệp này thường lớn hơn các tệp nguồn ban đầu. Đặt chúng vào kho lưu trữ có nghĩa là mọi người hiện cần tải xuống và lưu trữ các tệp được tạo đó, ngay cả khi họ không sử dụng chúng

Điểm thứ hai này dẫn đến một quy tắc chung khác về Git repos. cam kết các tệp nhị phân một cách thận trọng và đặc biệt tránh cam kết các tệp lớn. Quy tắc này liên quan nhiều đến cách hoạt động của Git

Git không lưu trữ bản sao đầy đủ của từng phiên bản của từng tệp bạn cam kết. Thay vào đó, nó sử dụng một thuật toán phức tạp dựa trên sự khác biệt giữa các phiên bản tiếp theo của một tệp để giảm đáng kể dung lượng lưu trữ mà nó cần. Các tệp nhị phân [như tệp JPG hoặc tệp MP3] không thực sự có các công cụ tìm khác biệt tốt, vì vậy Git thường chỉ cần lưu trữ toàn bộ tệp mỗi khi nó được cam kết

Khi bạn đang làm việc với Git và đặc biệt là khi bạn đang làm việc với GitHub, đừng bao giờ đưa thông tin bí mật vào repo, đặc biệt là thông tin bạn có thể chia sẻ công khai. Điều này quan trọng đến mức tôi sẽ nói lại lần nữa

thận trọng. Không bao giờ đưa thông tin bí mật vào kho lưu trữ công khai trên GitHub. Mật khẩu, khóa API và các mục tương tự không được cam kết với một repo. Ai đó sẽ tìm thấy chúng cuối cùng

Qua một bên. SHA là gì

Khi Git lưu trữ mọi thứ [tệp, thư mục, xác nhận, v.v.] trong repo của bạn, nó sẽ lưu trữ chúng theo cách phức tạp liên quan đến hàm băm. Chúng ta không cần đi sâu vào chi tiết ở đây, nhưng một hàm băm nhận một thứ và tạo ra một ID duy nhất cho thứ đó ngắn hơn nhiều [trong trường hợp của chúng tôi là 20 byte]. ID này được gọi là “SHA” trong Git. Nó không được đảm bảo là duy nhất, nhưng đối với hầu hết các ứng dụng thực tế thì nó là

Git sử dụng thuật toán băm của nó để lập chỉ mục mọi thứ trong repo của bạn. Mỗi tệp có một SHA phản ánh nội dung của tệp đó. Lần lượt từng thư mục được băm. Nếu một tệp trong thư mục đó thay đổi, thì SHA của thư mục cũng thay đổi

Mỗi cam kết chứa SHA của thư mục cấp cao nhất trong repo của bạn cùng với một số thông tin khác. Đó là cách một số 20 byte duy nhất mô tả toàn bộ trạng thái của repo của bạn

Bạn có thể nhận thấy rằng đôi khi Git sử dụng giá trị 20 ký tự đầy đủ để hiển thị cho bạn SHA

$ mkdir example
$ cd example
$ git init
Initialized empty Git repository in /home/jima/tmp/example/.git/
8

Đôi khi nó hiển thị cho bạn một phiên bản ngắn hơn

$ mkdir example
$ cd example
$ git init
Initialized empty Git repository in /home/jima/tmp/example/.git/
9

Thông thường, nó sẽ hiển thị cho bạn chuỗi ký tự đầy đủ, nhưng không phải lúc nào bạn cũng phải sử dụng nó. Quy tắc cho Git là bạn chỉ phải cung cấp đủ ký tự để đảm bảo rằng SHA là duy nhất trong repo của bạn. Nói chung, bảy ký tự là quá đủ

Mỗi khi bạn thực hiện các thay đổi đối với repo, Git sẽ tạo một SHA mới mô tả trạng thái đó. Chúng ta sẽ xem SHA hữu ích như thế nào trong các phần tiếp theo

Loại bỏ các quảng cáo

Nhật ký Git

Một lệnh Git được sử dụng rất thường xuyên khác là

# myname.py
def get_name[]:
    return "Jim"
9. Nhật ký Git hiển thị cho bạn lịch sử của các cam kết mà bạn đã thực hiện cho đến thời điểm này

$ git status
On branch master

Initial commit

nothing to commit [create/copy files and use "git add" to track]
0

Như bạn có thể thấy trong danh sách trên, tất cả các thông báo cam kết được hiển thị cho repo của chúng tôi theo thứ tự. Bắt đầu mỗi lần xác nhận được đánh dấu bằng từ "cam kết" theo sau là SHA của lần xác nhận đó.

# myname.py
def get_name[]:
    return "Jim"
9 cung cấp cho bạn lịch sử của từng SHA

Quay ngược thời gian. Kiểm tra phiên bản cụ thể của mã của bạn

Vì Git ghi nhớ từng cam kết bạn đã thực hiện với SHA, nên bạn có thể yêu cầu Git truy cập bất kỳ cam kết nào trong số đó và xem repo khi nó tồn tại sau đó. Sơ đồ bên dưới cho thấy những gì Git nghĩ là trong repo của chúng tôi

Đừng lo lắng về ý nghĩa của

# hello.py
print['hello Git!']
8 và
# hello.py
import myname

name = myname.get_name[]
print["hello {}".format[name]]
2 trong sơ đồ. Chúng tôi sẽ giải thích những điều đó chỉ trong một chút

Để thay đổi vị trí của chúng tôi trong lịch sử của mình, chúng tôi sẽ sử dụng lệnh

# hello.py
import myname

name = myname.get_name[]
print["hello {}".format[name]]
3 để cho Git biết SHA nào chúng tôi muốn xem xét. Hãy thử điều đó

$ git status
On branch master

Initial commit

nothing to commit [create/copy files and use "git add" to track]
1

OK, vì vậy có RẤT NHIỀU thông tin ở đây gây nhầm lẫn. Hãy bắt đầu bằng cách định nghĩa một số thuật ngữ đó. Hãy bắt đầu với

# hello.py
import myname

name = myname.get_name[]
print["hello {}".format[name]]
2

# hello.py
import myname

name = myname.get_name[]
print["hello {}".format[name]]
2 là tên của Git cho bất kỳ SHA nào bạn tình cờ xem bất cứ lúc nào. Nó KHÔNG có nghĩa là những gì có trên hệ thống tệp của bạn hoặc những gì có trong khu vực tổ chức của bạn. Nó có nghĩa là những gì Git nghĩ bạn đã kiểm tra. Vì vậy, nếu bạn đã chỉnh sửa một tệp, thì phiên bản trên hệ thống tệp của bạn khác với phiên bản trong
# hello.py
import myname

name = myname.get_name[]
print["hello {}".format[name]]
2 [và đúng vậy, HEAD được viết HOA]

Tiếp theo, chúng ta có

# hello.py
import myname

name = myname.get_name[]
print["hello {}".format[name]]
7. Cách dễ nhất để nghĩ về một nhánh là nó là nhãn trên SHA. Nó có một số thuộc tính hữu ích khác, nhưng hiện tại, hãy coi nhánh là nhãn SHA

Ghi chú. Những người trong số các bạn đã làm việc với các hệ thống kiểm soát phiên bản khác [Tôi đang tìm hiểu về bạn, Subversion] sẽ có một ý tưởng rất khác về nhánh là gì. Git đối xử với các nhánh khác nhau và đó là một điều tốt

Khi chúng tôi đặt tất cả thông tin này lại với nhau, chúng tôi thấy rằng HEAD tách rời chỉ có nghĩa là HEAD của bạn đang trỏ đến một SHA không có nhánh [hoặc nhãn] được liên kết với nó. Git rất hay cho bạn biết cách khắc phục tình trạng đó. Sẽ có lúc bạn muốn sửa nó, và sẽ có lúc bạn có thể làm việc ở trạng thái HEAD tách rời đó mà vẫn ổn.

Hãy quay lại bản demo của chúng tôi. Nếu bạn nhìn vào trạng thái của hệ thống bây giờ, bạn có thể thấy rằng tệp

$ git add hello.py
$ git status
On branch master

Initial commit

Changes to be committed:
  [use "git rm --cached ..." to unstage]

   new file:   hello.py
2 không còn nữa. Chúng tôi đã quay lại trạng thái của hệ thống trước khi thực hiện những thay đổi đó. Dưới đây là sơ đồ repo của chúng tôi ở trạng thái này. Lưu ý cách con trỏ
# hello.py
import myname

name = myname.get_name[]
print["hello {}".format[name]]
2 và
# hello.py
print['hello Git!']
8 trỏ vào các SHA khác nhau

Ổn thỏa. Bây giờ, làm thế nào để chúng ta trở lại nơi chúng ta đã ở? .

$ ls
hello.py  myname.py
$ ./hello.py
hello Jim!
$ ls
hello.py  myname.py  __pycache__
1. Điều này sẽ đưa bạn trở lại SHA mà bạn đang ở khi bạn bắt đầu di chuyển xung quanh

Ghi chú. Một điều kỳ lạ, ít nhất là trong phiên bản Git của tôi, là nó vẫn đưa ra cảnh báo HEAD tách rời, mặc dù bạn đã quay lại SHA được liên kết với một nhánh

Cách khác để quay lại phổ biến hơn. kiểm tra chi nhánh bạn đã ở trên. Git luôn bắt đầu với một nhánh tên là

# hello.py
print['hello Git!']
8. Chúng ta sẽ học cách tạo các nhánh khác sau nhưng bây giờ chúng ta sẽ gắn bó với
# hello.py
print['hello Git!']
8

Để quay lại nơi bạn đang ở, bạn chỉ cần thực hiện _

$ ls
hello.py  myname.py
$ ./hello.py
hello Jim!
$ ls
hello.py  myname.py  __pycache__
4. Điều này sẽ đưa bạn trở lại SHA mới nhất được cam kết với nhánh
# hello.py
print['hello Git!']
8, trong trường hợp của chúng tôi có thông báo cam kết “đã tạo. gitignore”. Nói cách khác,
$ ls
hello.py  myname.py
$ ./hello.py
hello Jim!
$ ls
hello.py  myname.py  __pycache__
4 yêu cầu Git đặt HEAD trỏ tới SHA được đánh dấu bằng nhãn hoặc nhánh,
# hello.py
print['hello Git!']
8

Lưu ý rằng có một số phương pháp để chỉ định một cam kết cụ thể. SHA có lẽ là dễ hiểu nhất. Các phương thức khác sử dụng các ký hiệu và tên khác nhau để chỉ định cách truy cập một cam kết cụ thể từ một địa điểm đã biết, chẳng hạn như HEAD. Tôi sẽ không đi sâu vào những chi tiết đó trong hướng dẫn này, nhưng nếu bạn muốn biết thêm chi tiết, bạn có thể tìm thấy chúng ở đây

Loại bỏ các quảng cáo

Khái niệm cơ bản về phân nhánh

Hãy nói thêm một chút về các chi nhánh. Các nhánh cung cấp một cách để bạn tách biệt các luồng phát triển riêng biệt. Mặc dù điều này có thể hữu ích khi bạn làm việc một mình, nhưng nó gần như cần thiết khi bạn làm việc theo nhóm

Hãy tưởng tượng rằng tôi đang làm việc trong một nhóm nhỏ và có một tính năng cần thêm vào dự án. Trong khi tôi đang làm việc với nó, tôi không muốn thêm các thay đổi của mình vào

# hello.py
print['hello Git!']
8 vì nó vẫn không hoạt động chính xác và có thể làm phiền các thành viên trong nhóm của tôi

Tôi chỉ có thể đợi để thực hiện các thay đổi cho đến khi tôi hoàn thành xong, nhưng điều đó không an toàn lắm và không phải lúc nào cũng thực tế. Vì vậy, thay vì làm việc trên

# hello.py
print['hello Git!']
8, tôi sẽ tạo một nhánh mới

$ git status
On branch master

Initial commit

nothing to commit [create/copy files and use "git add" to track]
2

Chúng tôi đã sử dụng tùy chọn

$ mkdir example
$ cd example
$ git init
Initialized empty Git repository in /home/jima/tmp/example/.git/
00 trên lệnh
$ mkdir example
$ cd example
$ git init
Initialized empty Git repository in /home/jima/tmp/example/.git/
01 để nói với Git rằng chúng tôi muốn nó tạo một nhánh mới. Như bạn có thể thấy ở trên, chạy
# hello.py
print['hello Git!']
7 trong nhánh của chúng tôi cho chúng tôi thấy rằng tên nhánh thực sự đã thay đổi. Hãy nhìn vào nhật ký

$ git status
On branch master

Initial commit

nothing to commit [create/copy files and use "git add" to track]
3

Như tôi hy vọng bạn mong đợi, nhật ký trông giống hệt như vậy. Khi bạn tạo một nhánh mới, nhánh mới sẽ bắt đầu tại vị trí bạn đã ở. Trong trường hợp này, chúng tôi đang ở trên cùng của master,

$ mkdir example
$ cd example
$ git init
Initialized empty Git repository in /home/jima/tmp/example/.git/
03, vì vậy đó là nơi nhánh mới bắt đầu

Bây giờ, hãy làm việc với tính năng đó. Thực hiện thay đổi đối với tệp

# hello.py
print['hello Git!']
9 và cam kết nó. Tôi sẽ hiển thị cho bạn các lệnh để xem xét, nhưng tôi sẽ ngừng hiển thị cho bạn đầu ra của các lệnh cho những thứ bạn đã xem

$ git status
On branch master

Initial commit

nothing to commit [create/copy files and use "git add" to track]
4

Bây giờ nếu bạn làm

# myname.py
def get_name[]:
    return "Jim"
9, bạn sẽ thấy cam kết mới của chúng tôi hiện diện. Trong trường hợp của tôi, nó có SHA 4a4f4492ded256aa7b29bf5176a17f9eda66efbb, nhưng repo của bạn rất có thể có SHA khác

$ git status
On branch master

Initial commit

nothing to commit [create/copy files and use "git add" to track]
5

Bây giờ quay trở lại nhánh chính và xem nhật ký

$ git status
On branch master

Initial commit

nothing to commit [create/copy files and use "git add" to track]
6

Cam kết mới "đã thêm mã cho tính năng x" có ở đó không?

Git có sẵn cách so sánh trạng thái của 2 nhánh nên bạn không cần phải vất vả. Đó là lệnh

$ mkdir example
$ cd example
$ git init
Initialized empty Git repository in /home/jima/tmp/example/.git/
06. Đây là những gì nó trông giống như

$ git status
On branch master

Initial commit

nothing to commit [create/copy files and use "git add" to track]
7

Lúc đầu, biểu đồ mà nó tạo ra hơi khó hiểu, vì vậy hãy cùng tìm hiểu chi tiết về nó. Trước hết, bạn gọi lệnh bằng cách đặt tên cho hai nhánh. Trong trường hợp của chúng tôi, đó là

$ mkdir example
$ cd example
$ git init
Initialized empty Git repository in /home/jima/tmp/example/.git/
07 và
# hello.py
print['hello Git!']
8

Hai dòng đầu tiên của đầu ra là chìa khóa để giải mã phần còn lại của văn bản. Ký tự không phải khoảng trắng đầu tiên trên mỗi dòng là

$ mkdir example
$ cd example
$ git init
Initialized empty Git repository in /home/jima/tmp/example/.git/
09 hoặc
$ mkdir example
$ cd example
$ git init
Initialized empty Git repository in /home/jima/tmp/example/.git/
10 theo sau là tên của nhánh và sau đó là thông báo cam kết cho lần xác nhận gần đây nhất trên nhánh đó. Ký tự
$ mkdir example
$ cd example
$ git init
Initialized empty Git repository in /home/jima/tmp/example/.git/
09 được sử dụng để chỉ ra rằng chi nhánh hiện đang được trả phòng trong khi
$ mkdir example
$ cd example
$ git init
Initialized empty Git repository in /home/jima/tmp/example/.git/
10 được sử dụng cho tất cả các chi nhánh khác. Ký tự nằm trong cột khớp với các cam kết trong bảng bên dưới

Dòng thứ ba là dấu phân cách

Bắt đầu từ dòng thứ tư, có các xác nhận nằm trong một nhánh chứ không phải nhánh kia. Trong trường hợp hiện tại của chúng tôi, điều này khá dễ dàng. Có một cam kết trong

$ mkdir example
$ cd example
$ git init
Initialized empty Git repository in /home/jima/tmp/example/.git/
07 không có trong master. Bạn có thể thấy điều đó ở dòng thứ tư. Lưu ý cách dòng đó bắt đầu bằng
$ mkdir example
$ cd example
$ git init
Initialized empty Git repository in /home/jima/tmp/example/.git/
09 trong cột đầu tiên. Điều này là để cho biết cam kết này nằm trong nhánh nào

Cuối cùng, dòng cuối cùng của đầu ra hiển thị cam kết chung đầu tiên cho hai nhánh

Ví dụ này khá dễ. Để tạo một ví dụ tốt hơn, tôi đã làm cho nó thú vị hơn bằng cách thêm một vài cam kết vào

$ mkdir example
$ cd example
$ git init
Initialized empty Git repository in /home/jima/tmp/example/.git/
07 và một vài cam kết vào
$ mkdir example
$ cd example
$ git init
Initialized empty Git repository in /home/jima/tmp/example/.git/
16 Điều đó làm cho đầu ra trông giống như

$ git status
On branch master

Initial commit

nothing to commit [create/copy files and use "git add" to track]
8

Bây giờ bạn có thể thấy rằng có các cam kết khác nhau trong mỗi nhánh. Lưu ý rằng văn bản

$ mkdir example
$ cd example
$ git init
Initialized empty Git repository in /home/jima/tmp/example/.git/
17 là một trong những phương pháp lựa chọn cam kết mà tôi đã đề cập trước đó. Nếu bạn muốn xem SHA, bạn có thể yêu cầu nó hiển thị chúng bằng cách thêm tùy chọn –sha1-name vào lệnh

$ git status
On branch master

Initial commit

nothing to commit [create/copy files and use "git add" to track]
9

Bây giờ bạn đã có một nhánh với một loạt các cam kết khác nhau trên đó. Bạn sẽ làm gì khi cuối cùng cũng hoàn thành tính năng đó và sẵn sàng cung cấp tính năng đó cho các thành viên còn lại trong nhóm của mình?

Có ba cách chính để nhận các cam kết từ nhánh này sang nhánh khác. hợp nhất, nổi loạn và hái anh đào. Chúng tôi sẽ lần lượt đề cập đến từng vấn đề này trong các phần tiếp theo

Loại bỏ các quảng cáo

sáp nhập

Hợp nhất là cách đơn giản nhất trong ba cách để hiểu và sử dụng. Khi bạn hợp nhất, Git sẽ tạo một cam kết mới kết hợp các SHA hàng đầu của hai nhánh nếu cần. Nếu tất cả các xác nhận trong nhánh khác ở phía trước [dựa trên] đỉnh của nhánh hiện tại, thì nó sẽ thực hiện hợp nhất chuyển tiếp nhanh và đặt các xác nhận mới đó vào nhánh này

Hãy sao lưu đến điểm mà đầu ra nhánh hiển thị của chúng tôi trông như thế này

# hello.py
print['hello Git!']
0

Bây giờ, chúng tôi muốn cam kết đó

$ mkdir example
$ cd example
$ git init
Initialized empty Git repository in /home/jima/tmp/example/.git/
18 trở thành chủ. Kiểm tra master và chạy lệnh
$ mkdir example
$ cd example
$ git init
Initialized empty Git repository in /home/jima/tmp/example/.git/
19 ở đó

# hello.py
print['hello Git!']
1

Vì chúng tôi ở trên nhánh chính, chúng tôi đã hợp nhất nhánh my_new_feature với chúng tôi. Bạn có thể thấy rằng đây là một sự hợp nhất chuyển tiếp nhanh và những tệp nào đã được thay đổi. Bây giờ hãy nhìn vào nhật ký

# hello.py
print['hello Git!']
2

Nếu chúng tôi đã thực hiện các thay đổi đối với chủ trước khi hợp nhất, Git sẽ tạo một cam kết mới là sự kết hợp của các thay đổi từ hai nhánh

Một trong những điều Git khá giỏi là hiểu tổ tiên chung của các nhánh khác nhau và tự động hợp nhất các thay đổi lại với nhau. Nếu cùng một đoạn mã đã được sửa đổi ở cả hai nhánh, Git không thể biết phải làm gì. Khi điều này xảy ra, quá trình hợp nhất sẽ dừng một phần và cung cấp cho bạn hướng dẫn về cách khắc phục sự cố. Đây được gọi là xung đột hợp nhất

nổi loạn

Rebasing tương tự như hợp nhất nhưng hoạt động hơi khác một chút. Trong quá trình hợp nhất, nếu cả hai nhánh có thay đổi, thì một cam kết hợp nhất mới được tạo. Khi khởi động lại, Git sẽ lấy các xác nhận từ một nhánh và phát lại chúng, từng cái một, trên đỉnh của nhánh kia

Tôi sẽ không thực hiện bản trình diễn chi tiết về việc nổi loạn ở đây vì việc thiết lập một bản trình diễn để hiển thị điều này hơi phức tạp về mặt văn bản và vì có một trang web tuyệt vời trình bày tốt về chủ đề này và tôi sẽ tham khảo ở cuối phần này

anh đào hái

Hái quả anh đào là một phương pháp khác để di chuyển cam kết từ nhánh này sang nhánh khác. Không giống như hợp nhất và khởi động lại, với tính năng chọn anh đào, bạn chỉ định chính xác cam kết mà bạn muốn nói. Cách dễ nhất để làm điều này là chỉ định một SHA duy nhất

# hello.py
print['hello Git!']
3

Điều này yêu cầu Git thực hiện các thay đổi trong

$ mkdir example
$ cd example
$ git init
Initialized empty Git repository in /home/jima/tmp/example/.git/
18 và áp dụng chúng cho nhánh hiện tại

Tính năng này có thể rất hữu ích khi bạn muốn một thay đổi cụ thể chứ không phải toàn bộ nhánh đã thực hiện thay đổi đó

Mẹo nhanh về phân nhánh. Tôi không thể rời khỏi chủ đề này mà không đề xuất một tài nguyên tuyệt vời để tìm hiểu về các nhánh Git. Tìm hiểu Phân nhánh Git có một tập hợp các bài tập sử dụng biểu diễn đồ họa của các cam kết và nhánh để giải thích rõ ràng sự khác biệt giữa hợp nhất, khởi động lại và chọn anh đào. Tôi thực sự khuyên bạn nên dành thời gian làm việc thông qua các bài tập này

Làm việc với Repos từ xa

Tất cả các lệnh chúng tôi đã thảo luận cho đến thời điểm này chỉ hoạt động với kho lưu trữ cục bộ của bạn. Họ không thực hiện bất kỳ giao tiếp nào với máy chủ hoặc qua mạng. Hóa ra chỉ có bốn lệnh Git chính thực sự nói chuyện với các kho lưu trữ từ xa

  • $ mkdir example
    $ cd example
    $ git init
    Initialized empty Git repository in /home/jima/tmp/example/.git/
    
    21
  • $ mkdir example
    $ cd example
    $ git init
    Initialized empty Git repository in /home/jima/tmp/example/.git/
    
    22
  • $ mkdir example
    $ cd example
    $ git init
    Initialized empty Git repository in /home/jima/tmp/example/.git/
    
    23
  • $ mkdir example
    $ cd example
    $ git init
    Initialized empty Git repository in /home/jima/tmp/example/.git/
    
    24

Đó là nó. Mọi thứ khác được thực hiện trên máy cục bộ của bạn. [OK, hoàn toàn chính xác, có những lệnh khác nói chuyện với điều khiển từ xa, nhưng chúng không thuộc danh mục cơ bản. ]

Hãy lần lượt xem xét từng lệnh này

Loại bỏ các quảng cáo

$ mkdir example
$ cd example
$ git init
Initialized empty Git repository in /home/jima/tmp/example/.git/
25

Git

$ mkdir example
$ cd example
$ git init
Initialized empty Git repository in /home/jima/tmp/example/.git/
21 là lệnh bạn sử dụng khi bạn có địa chỉ của một kho lưu trữ đã biết và bạn muốn tạo một bản sao cục bộ. Đối với ví dụ này, hãy sử dụng một repo nhỏ mà tôi có trên tài khoản GitHub của mình, github-playground

Trang GitHub cho repo đó tồn tại ở đây. Trên trang đó, bạn sẽ tìm thấy nút “Sao chép hoặc Tải xuống” cung cấp cho bạn URI để sử dụng với lệnh

$ mkdir example
$ cd example
$ git init
Initialized empty Git repository in /home/jima/tmp/example/.git/
27. Nếu bạn sao chép nó, thì bạn có thể
$ mkdir example
$ cd example
$ git init
Initialized empty Git repository in /home/jima/tmp/example/.git/
21 repo với

# hello.py
print['hello Git!']
4

Bây giờ bạn có một kho lưu trữ hoàn chỉnh của dự án đó trên máy cục bộ của mình. Điều này bao gồm tất cả các cam kết và tất cả các nhánh từng được thực hiện trên đó. [Ghi chú. Repo này đã được một số người bạn sử dụng khi họ đang học Git. Tôi đã sao chép hoặc rẽ nhánh nó từ người khác. ]

Nếu bạn muốn chơi với các lệnh từ xa khác, bạn nên tạo một repo mới trên GitHub và làm theo các bước tương tự. Bạn có thể rẽ nhánh kho lưu trữ

$ mkdir example
$ cd example
$ git init
Initialized empty Git repository in /home/jima/tmp/example/.git/
29 vào tài khoản của mình và sử dụng. Việc rẽ nhánh trên GitHub được thực hiện bằng cách nhấp vào nút “rẽ nhánh” trong giao diện người dùng

$ mkdir example
$ cd example
$ git init
Initialized empty Git repository in /home/jima/tmp/example/.git/
30

Để giải thích rõ ràng về lệnh

$ mkdir example
$ cd example
$ git init
Initialized empty Git repository in /home/jima/tmp/example/.git/
22, chúng ta cần lùi lại một bước và nói về cách Git quản lý mối quan hệ giữa repo cục bộ của bạn và repo từ xa. Phần tiếp theo này là thông tin cơ bản và mặc dù đây không phải là thứ bạn sẽ sử dụng hàng ngày, nhưng nó sẽ tạo ra sự khác biệt giữa
$ mkdir example
$ cd example
$ git init
Initialized empty Git repository in /home/jima/tmp/example/.git/
22 và
$ mkdir example
$ cd example
$ git init
Initialized empty Git repository in /home/jima/tmp/example/.git/
23 có ý nghĩa hơn

Khi bạn

$ mkdir example
$ cd example
$ git init
Initialized empty Git repository in /home/jima/tmp/example/.git/
21 một repo mới, Git không chỉ sao chép một phiên bản duy nhất của các tệp trong dự án đó. Nó sao chép toàn bộ kho lưu trữ và sử dụng nó để tạo một kho lưu trữ mới trên máy cục bộ của bạn

Git không tạo các nhánh cục bộ cho bạn ngoại trừ master. Tuy nhiên, nó theo dõi các chi nhánh trên máy chủ. Để làm điều đó, Git tạo một tập hợp các nhánh bắt đầu bằng

$ mkdir example
$ cd example
$ git init
Initialized empty Git repository in /home/jima/tmp/example/.git/
35

Chỉ hiếm khi [hầu như không bao giờ], bạn sẽ kiểm tra các chi nhánh

$ mkdir example
$ cd example
$ git init
Initialized empty Git repository in /home/jima/tmp/example/.git/
36 này, nhưng thật hữu ích khi biết rằng chúng ở đó. Hãy nhớ rằng mọi nhánh tồn tại trên điều khiển từ xa khi bạn nhân bản repo sẽ có một nhánh trong
$ mkdir example
$ cd example
$ git init
Initialized empty Git repository in /home/jima/tmp/example/.git/
36

Khi bạn tạo một nhánh mới và tên khớp với một nhánh hiện có trên máy chủ, Git sẽ đánh dấu nhánh cục bộ của bạn là nhánh theo dõi được liên kết với nhánh từ xa. Chúng ta sẽ thấy điều đó hữu ích như thế nào khi chúng ta đến

$ mkdir example
$ cd example
$ git init
Initialized empty Git repository in /home/jima/tmp/example/.git/
23

Bây giờ bạn đã biết về các nhánh của

$ mkdir example
$ cd example
$ git init
Initialized empty Git repository in /home/jima/tmp/example/.git/
36, việc hiểu về
$ mkdir example
$ cd example
$ git init
Initialized empty Git repository in /home/jima/tmp/example/.git/
40 sẽ khá dễ dàng. Tất cả những gì
$ mkdir example
$ cd example
$ git init
Initialized empty Git repository in /home/jima/tmp/example/.git/
22 làm là cập nhật tất cả các nhánh của
$ mkdir example
$ cd example
$ git init
Initialized empty Git repository in /home/jima/tmp/example/.git/
36. Nó sẽ chỉ sửa đổi các nhánh được lưu trữ trong
$ mkdir example
$ cd example
$ git init
Initialized empty Git repository in /home/jima/tmp/example/.git/
36 chứ không phải bất kỳ nhánh địa phương nào của bạn

$ mkdir example
$ cd example
$ git init
Initialized empty Git repository in /home/jima/tmp/example/.git/
44

$ mkdir example
$ cd example
$ git init
Initialized empty Git repository in /home/jima/tmp/example/.git/
45 chỉ đơn giản là sự kết hợp của hai lệnh khác. Đầu tiên, nó thực hiện một
$ mkdir example
$ cd example
$ git init
Initialized empty Git repository in /home/jima/tmp/example/.git/
40 để cập nhật các nhánh
$ mkdir example
$ cd example
$ git init
Initialized empty Git repository in /home/jima/tmp/example/.git/
36. Sau đó, nếu chi nhánh bạn đang theo dõi một chi nhánh từ xa, thì chi nhánh đó sẽ thực hiện
$ mkdir example
$ cd example
$ git init
Initialized empty Git repository in /home/jima/tmp/example/.git/
19 của chi nhánh
$ mkdir example
$ cd example
$ git init
Initialized empty Git repository in /home/jima/tmp/example/.git/
49 tương ứng với chi nhánh của bạn

Ví dụ: giả sử bạn đang ở nhánh my_new_feature và đồng nghiệp của bạn vừa thêm một số mã vào nhánh đó trên máy chủ. Nếu bạn thực hiện

$ mkdir example
$ cd example
$ git init
Initialized empty Git repository in /home/jima/tmp/example/.git/
50, Git sẽ cập nhật TẤT CẢ các nhánh của
$ mkdir example
$ cd example
$ git init
Initialized empty Git repository in /home/jima/tmp/example/.git/
36 và sau đó thực hiện
$ mkdir example
$ cd example
$ git init
Initialized empty Git repository in /home/jima/tmp/example/.git/
52, thao tác này sẽ nhận được cam kết mới vào nhánh mà bạn đang thực hiện

Tất nhiên, có một số hạn chế ở đây. Git thậm chí sẽ không cho phép bạn thử thực hiện

$ mkdir example
$ cd example
$ git init
Initialized empty Git repository in /home/jima/tmp/example/.git/
50 nếu bạn đã sửa đổi các tệp trên hệ thống cục bộ của mình. Điều đó có thể tạo ra quá nhiều lộn xộn

Nếu bạn có các cam kết trên chi nhánh địa phương của mình và điều khiển từ xa cũng có các cam kết mới [tức là “các nhánh đã chuyển hướng”], thì phần

$ mkdir example
$ cd example
$ git init
Initialized empty Git repository in /home/jima/tmp/example/.git/
19 của
$ mkdir example
$ cd example
$ git init
Initialized empty Git repository in /home/jima/tmp/example/.git/
23 sẽ tạo ra một cam kết hợp nhất, giống như chúng ta đã thảo luận ở trên

Những ai đã đọc kỹ sẽ thấy rằng bạn cũng có thể yêu cầu Git thực hiện rebase thay vì hợp nhất bằng cách thực hiện

$ mkdir example
$ cd example
$ git init
Initialized empty Git repository in /home/jima/tmp/example/.git/
56

$ mkdir example
$ cd example
$ git init
Initialized empty Git repository in /home/jima/tmp/example/.git/
57

Như bạn có thể đoán,

$ mkdir example
$ cd example
$ git init
Initialized empty Git repository in /home/jima/tmp/example/.git/
58 hoàn toàn ngược lại với
$ mkdir example
$ cd example
$ git init
Initialized empty Git repository in /home/jima/tmp/example/.git/
50. Vâng, gần như ngược lại.
$ mkdir example
$ cd example
$ git init
Initialized empty Git repository in /home/jima/tmp/example/.git/
57 gửi thông tin về nhánh bạn đang đẩy và hỏi điều khiển từ xa xem nó có muốn cập nhật phiên bản của nhánh đó để phù hợp với phiên bản của bạn không

Nói chung, điều này tương đương với việc bạn đẩy các thay đổi mới của mình lên máy chủ. Có rất nhiều chi tiết và sự phức tạp ở đây liên quan đến chính xác cam kết chuyển tiếp nhanh là gì

Có một bài viết tuyệt vời ở đây. Ý chính của nó là

$ mkdir example
$ cd example
$ git init
Initialized empty Git repository in /home/jima/tmp/example/.git/
58 cung cấp các cam kết mới của bạn trên máy chủ từ xa

Loại bỏ các quảng cáo

Để tất cả chúng cùng nhau. Quy trình công việc Git đơn giản

Tại thời điểm này, chúng tôi đã xem xét một số lệnh Git cơ bản và cách bạn có thể sử dụng chúng. Tôi sẽ kết thúc bằng phần mô tả nhanh về quy trình làm việc có thể có trong Git. Quy trình công việc này giả định rằng bạn đang làm việc trên kho lưu trữ cục bộ của mình và có một kho lưu trữ từ xa mà bạn sẽ

$ mkdir example
$ cd example
$ git init
Initialized empty Git repository in /home/jima/tmp/example/.git/
24 thay đổi. Nó có thể là GitHub, nhưng nó sẽ hoạt động tương tự với các repo từ xa khác. Nó giả định rằng bạn đã nhân bản repo

  1. # hello.py
    print['hello Git!']
    
    7 – Đảm bảo khu vực hiện tại của bạn sạch sẽ
  2. $ mkdir example
    $ cd example
    $ git init
    Initialized empty Git repository in /home/jima/tmp/example/.git/
    
    50 – Nhận phiên bản mới nhất từ ​​xa. Điều này tiết kiệm các vấn đề hợp nhất sau này
  3. Chỉnh sửa các tệp của bạn và thực hiện các thay đổi của bạn. Hãy nhớ chạy kẻ nói dối của bạn và làm bài kiểm tra đơn vị
  4. # hello.py
    print['hello Git!']
    
    7 – Tìm tất cả các tệp được thay đổi. Đảm bảo cũng xem các tệp không bị theo dõi
  5. $ mkdir example
    $ cd example
    $ git init
    Initialized empty Git repository in /home/jima/tmp/example/.git/
    
    66 – Thêm các tệp đã thay đổi vào khu vực tổ chức
  6. $ mkdir example
    $ cd example
    $ git init
    Initialized empty Git repository in /home/jima/tmp/example/.git/
    
    67 – Thực hiện cam kết mới của bạn
  7. $ mkdir example
    $ cd example
    $ git init
    Initialized empty Git repository in /home/jima/tmp/example/.git/
    
    68 – Đẩy các thay đổi của bạn lên điều khiển từ xa

Đây là một trong những luồng cơ bản hơn thông qua hệ thống. Có rất, rất nhiều cách để sử dụng Git và bạn vừa mới tìm hiểu sơ bộ về hướng dẫn này. Nếu bạn sử dụng Vim hoặc Sublime làm trình chỉnh sửa của mình, bạn có thể muốn xem các hướng dẫn này, hướng dẫn này sẽ chỉ cho bạn cách tải plugin để tích hợp Git vào trình chỉnh sửa của bạn

  • VIM và Python – Trận đấu trời định
  • Thiết lập Sublime Text 3 để phát triển Full Stack Python
  • Emacs – Trình chỉnh sửa Python tốt nhất?

Nếu bạn muốn tìm hiểu sâu hơn về Git, tôi có thể giới thiệu những cuốn sách này

  • Pro Git trực tuyến, miễn phí là một tài liệu tham khảo rất hữu ích
  • Đối với những bạn thích đọc trên giấy, có một phiên bản in của Pro Git và tôi thấy Kiểm soát phiên bản của O'Reilly với Git rất hữu ích

Cuối cùng, nếu bạn quan tâm đến việc khai thác sức mạnh của trí tuệ nhân tạo trong hành trình viết mã của mình, thì bạn có thể thử với GitHub Copilot

Đánh dấu là đã hoàn thành

Xem ngay Hướng dẫn này có một khóa học video liên quan do nhóm Real Python tạo. Xem nó cùng với hướng dẫn bằng văn bản để hiểu sâu hơn. Giới thiệu về Git và GitHub dành cho nhà phát triển Python

🐍 Thủ thuật Python 💌

Nhận một Thủ thuật Python ngắn và hấp dẫn được gửi đến hộp thư đến của bạn vài ngày một lần. Không có thư rác bao giờ. Hủy đăng ký bất cứ lúc nào. Được quản lý bởi nhóm Real Python

Gửi cho tôi thủ thuật Python »

Về Jim Anderson

Jim đã lập trình trong một thời gian dài bằng nhiều ngôn ngữ. Anh ấy đã làm việc trên các hệ thống nhúng, xây dựng các hệ thống xây dựng phân tán, quản lý nhà cung cấp nước ngoài và tham gia rất nhiều cuộc họp

» Thông tin thêm về Jim

Mỗi hướng dẫn tại Real Python được tạo bởi một nhóm các nhà phát triển để nó đáp ứng các tiêu chuẩn chất lượng cao của chúng tôi. Các thành viên trong nhóm đã làm việc trong hướng dẫn này là

Đan

Joanna

Bậc thầy Kỹ năng Python trong thế giới thực Với quyền truy cập không giới hạn vào Python thực

Tham gia với chúng tôi và có quyền truy cập vào hàng nghìn hướng dẫn, khóa học video thực hành và cộng đồng các Pythonistas chuyên gia

Nâng cao kỹ năng Python của bạn »

Chuyên gia Kỹ năng Python trong thế giới thực
Với quyền truy cập không giới hạn vào Python thực

Tham gia với chúng tôi và có quyền truy cập vào hàng ngàn hướng dẫn, khóa học video thực hành và cộng đồng Pythonistas chuyên gia

Nâng cao kỹ năng Python của bạn »

Bạn nghĩ sao?

Đánh giá bài viết này

Tweet Chia sẻ Chia sẻ Email

Bài học số 1 hoặc điều yêu thích mà bạn đã học được là gì?

Mẹo bình luận. Những nhận xét hữu ích nhất là những nhận xét được viết với mục đích học hỏi hoặc giúp đỡ các sinh viên khác. và nhận câu trả lời cho các câu hỏi phổ biến trong cổng thông tin hỗ trợ của chúng tôi

Tôi có thể sử dụng GitHub cho Python không?

GitHub cung cấp quy trình làm việc dành cho người mới bắt đầu Python phù hợp với hầu hết các dự án Python .

Tôi có thể thực hành Python cơ bản ở đâu?

Tôi có thể thực hành lập trình Python ở đâu? .
yêu cầu dữ liệu. io có hàng tá câu hỏi thực hành tương tác miễn phí, cũng như các bài học tương tác miễn phí, ý tưởng dự án, hướng dẫn, v.v.
HackerRank là một trang web tuyệt vời để thực hành cũng có tính tương tác
Codingame là một nền tảng thực hành thú vị hỗ trợ Python

Tôi có thể học Python cơ bản trong một ngày không?

Trung bình, có thể mất từ ​​5 đến 10 tuần để tìm hiểu kiến ​​thức cơ bản về lập trình Python, bao gồm lập trình hướng đối tượng, cơ bản .

Tôi có thể Thực hành Python miễn phí ở đâu?

10 khóa học Python miễn phí hàng đầu .
Lớp Python của Google. .
Khóa học Giới thiệu về Python của Microsoft. .
Giới thiệu về lập trình Python của Udemy. .
Học Python - Khóa học đầy đủ cho người mới bắt đầu của freeCodeCamp. .
Học Python 3 từ đầu bằng Educative. .
Python cho mọi người của Coursera. .
Tìm hiểu Python 2 bằng Codecademy

Chủ Đề