Git cho người dùng Perforce


86

Tôi đã sử dụng Perforce trong một số năm. Tôi muốn chuyển sang sử dụng git cho mã cá nhân của mình, nhưng tất cả các hướng dẫn về git mà tôi đã xem đều cho rằng bạn là người kiểm soát nguồn hoàn chỉnh n00b (điều này khiến chúng trở nên vô cùng tẻ nhạt) hoặc bạn đã quen với svn (mà tôi không phải).

Tôi biết p4 và tôi cũng hiểu ý tưởng đằng sau một hệ thống kiểm soát nguồn phân tán (vì vậy tôi không cần quảng cáo chiêu hàng, cảm ơn). Những gì tôi muốn là một bảng dịch từ lệnh p4 sang các lệnh git tương đương, cũng như các lệnh "không thể sống thiếu" không có lệnh tương đương p4.

Vì tôi nghi ngờ mọi người dùng p4 sử dụng một tập hợp con khác nhau của p4, đây là một số điều tôi thường xuyên làm trong p4 mà tôi muốn có thể thực hiện trong git mà không rõ ràng ngay lập tức từ các tài liệu tôi đã xem :

  1. tạo nhiều danh sách thay đổi đang chờ xử lý trong một ứng dụng khách. ( p4 change)
  2. chỉnh sửa danh sách thay đổi đang chờ xử lý. (còn nữa p4 change)
  3. xem danh sách tất cả các danh sách thay đổi đang chờ xử lý của tôi ( p4 changes -s pending)
  4. danh sách tất cả các tệp đã thay đổi trong ứng dụng khách của tôi ( p4 opened) hoặc trong danh sách thay đổi đang chờ xử lý ( p4 describe)
  5. thấy sự khác biệt của danh sách thay đổi đang chờ xử lý (tôi sử dụng tập lệnh trình bao bọc cho điều này sử dụng p4 diffp4 describe)
  6. cho một tệp nhất định, hãy xem danh sách thay đổi đã gửi nào ảnh hưởng đến dòng nào ( p4 annotate)
  7. đối với một tệp nhất định, hãy xem danh sách mô tả danh sách thay đổi đã ảnh hưởng đến tệp ( p4 log)
  8. gửi danh sách thay đổi đang chờ xử lý ( p4 submit -c)
  9. hủy bỏ danh sách thay đổi đang chờ xử lý ( p4 revert)

Rất nhiều trong số này xoay quanh "người thay đổi". "changelist" là thuật ngữ p4. Thuật ngữ tương đương git là gì?

Có vẻ như các nhánh có thể là thứ mà người dùng git sử dụng thay cho thứ mà p4 gọi là danh sách thay đổi. Một chút khó hiểu, vì p4 cũng có một cái gì đó được gọi là một nhánh mặc dù chúng dường như chỉ là những khái niệm liên quan mơ hồ. (Mặc dù tôi luôn nghĩ rằng khái niệm nhánh của p4 khá kỳ lạ nhưng nó lại khác với khái niệm RCS cổ điển về một nhánh.)

Dù sao thì ... tôi không chắc làm thế nào để hoàn thành những gì tôi thường làm trong danh sách thay đổi p4 với các nhánh của git. Trong p4, tôi có thể làm điều gì đó như sau:

$ p4 edit a.txt
$ p4 change a.txt
Change 12345 created.

Tại thời điểm này, tôi có một danh sách thay đổi có chứa a.txt. Tôi có thể chỉnh sửa mô tả và tiếp tục làm việc mà không cần gửi danh sách thay đổi. Ngoài ra, nếu hóa ra tôi cần thực hiện một số thay đổi đối với một số tệp khác, chẳng hạn như sửa lỗi trong một số lớp khác của mã, tôi có thể thực hiện điều đó trong cùng một ứng dụng khách:

$ p4 edit z.txt
$ p4 change z.txt
Change 12346 created.

Bây giờ tôi có hai danh sách thay đổi riêng biệt trong cùng một khách hàng. Tôi có thể làm việc trên những thứ này đồng thời và tôi không cần phải làm bất cứ điều gì để "chuyển đổi giữa" chúng. Khi đến thời điểm cam kết, tôi có thể gửi chúng một cách riêng biệt:

$ p4 submit -c 12346  # this will submit the changes to z.txt
$ p4 submit -c 12345  # this will submit the changes to a.txt

Tôi không thể tìm ra cách sao chép điều này trong git. Từ các thử nghiệm của tôi, nó dường như không git addđược liên kết với nhánh hiện tại. Theo như tôi có thể nói, khi tôi git commitsẽ cam kết tất cả các tệp mà tôi đã git add-ed bất kể tôi đang ở chi nhánh nào vào thời điểm đó:

$ git init
Initialized empty Git repository in /home/laurence/git-playground/.git/
$ ls
a.txt  w.txt  z.txt
$ git add -A .
$ git commit
 Initial commit.
 3 files changed, 3 insertions(+), 0 deletions(-)
 create mode 100644 a.txt
 create mode 100644 w.txt
 create mode 100644 z.txt
$ vi a.txt z.txt 
2 files to edit
$ git status
# On branch master
# Changed but not updated:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#   modified:   a.txt
#   modified:   z.txt
#
no changes added to commit (use "git add" and/or "git commit -a")
$ git branch aardvark
$ git checkout aardvark
M   a.txt
M   z.txt
Switched to branch 'aardvark'
$ git add a.txt 
$ git checkout master
M   a.txt
M   z.txt
Switched to branch 'master'
$ git branch zebra
$ git checkout zebra
M   a.txt
M   z.txt
Switched to branch 'zebra'
$ git add z.txt 
$ git status
# On branch zebra
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#   modified:   a.txt
#   modified:   z.txt
#
$ git checkout aardvark
M   a.txt
M   z.txt
Switched to branch 'aardvark'
$ git status
# On branch aardvark
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#   modified:   a.txt
#   modified:   z.txt

Trong ví dụ này, các nhánh aardvark và zebra dường như chứa chính xác cùng một tập hợp các thay đổi và dựa trên kết quả của git statusnó, có vẻ như việc thực hiện một cam kết trong một trong hai sẽ có cùng tác dụng. Tôi có làm điều gì sai?


2
Bạn chỉ có thể sử dụng perforce cho mã cá nhân của mình giả sử 5 khách hàng miễn phí là đủ.
Logan Capaldo

3
Đó là những gì tôi đang làm, nhưng tôi muốn chuyển sang thứ gì đó mã nguồn mở và cũng được sử dụng bởi các dự án mã nguồn mở. Tôi đã xem xét cả git và Mercurial. Tôi đã nghiêng về git vì nó dường như có nhiều động lực hơn.
Laurence Gonsalves

1
Tốt hơn bạn nên học Git từ đầu. Quy trình làm việc do Git quy định rất khác với quy trình làm việc do Perforce quy định. Quy trình công việc đã dịch sẽ rất khó hiểu và việc cố gắng đánh đồng các tính năng sẽ làm bạn khó hiểu. May mắn thay, cộng đồng Git cung cấp rất nhiều tài liệu cho người mới bắt đầu, ví dụ: git-scm.com/book
Colonel Panic

1
@ColonelPanic Tôi có thể hiểu quan điểm của bạn, nhưng vấn đề với tài liệu như vậy là lãng phí thời gian giải thích những điều cơ bản mà mọi người dùng Perforce đều đã biết. Đọc tài liệu như vậy cũng khó chịu như cố gắng đọc một hướng dẫn về ngôn ngữ lập trình khác dành một chương để giải thích các biến là gì.
Laurence Gonsalves

@ColonelPanic Điều đó nói rằng, tôi đã đọc một số tài liệu git khác, bao gồm Git From the Bottom UpGit dành cho các nhà khoa học máy tính thực sự khá hữu ích. Tôi đã sử dụng Git được vài năm rồi (lưu ý khi câu hỏi này ban đầu được hỏi) và tôi cảm thấy các vấn đề chính của việc học git không phải là thiếu tài liệu, mà là do danh pháp kém, không nhất quán nội bộ, các lệnh bị quá tải nặng và một số các bộ phận chưa hoàn thành chưa sẵn sàng để sử dụng thực tế. Tôi ước ai đó sẽ đi và dọn dẹp tất cả những thứ vụn vặt, nhưng điều đó sẽ làm phiền những người đã quen với nó.
Laurence Gonsalves

Câu trả lời:


72

Tôi chưa sử dụng perforce nhiều nên đây có thể không chính xác là bản dịch 1: 1. Sau đó, các hệ thống kiểm soát nguồn phân tán một lần nữa như git và thương mại có quy trình làm việc khác, vì vậy thực sự không (và không nên) có bản dịch 1: 1. Dù sao, đây là:

  • Tạo nhiều danh sách thay đổi đang chờ xử lý -> Sử dụng các nhánh thay thế. Trong git, các nhánh nhẹ và nhanh chóng, mất ít hơn một giây để tạo và thường ít hơn hai giây để hợp nhất. Đừng sợ rẽ nhánh và thường xuyên rebase.

    git branch new-branch-name
    git checkout new-branch-name
    

    Hoặc làm tất cả trong một dòng:

    git checkout -b new-branch-name
    
  • Xem danh sách tất cả danh sách thay đổi đang chờ xử lý -> Vì tương đương với nhiều danh sách thay đổi đang chờ xử lý là nhiều nhánh, chỉ cần xem các nhánh:

    git branch
    

    Nếu bạn cũng muốn xem các chi nhánh từ xa:

    git branch -a
    

    Việc xóa ngay một nhánh sau khi hợp nhất thành công được coi là một phương pháp hay để bạn không phải theo dõi nhánh nào đang chờ được hợp nhất và nhánh nào đã được hợp nhất.

  • Liệt kê tất cả các tệp đã thay đổi -> Đối với một "danh sách thay đổi" đang chờ xử lý trong một nhánh cụ thể, git có một khái niệm về chỉ mục hoặc bộ nhớ cache. Để thực hiện một thay đổi, trước tiên bạn phải thêm tệp vào chỉ mục này. Điều này cho phép bạn chọn theo cách thủ công nhóm tệp nào đại diện cho một thay đổi duy nhất hoặc bỏ qua các tệp không liên quan. Để xem trạng thái của những tệp nào được thêm vào hay không vào chỉ mục này, chỉ cần thực hiện:

    git status
    
  • Xem sự khác biệt của danh sách thay đổi đang chờ xử lý -> Có hai phần cho điều này. Đầu tiên hãy xem sự khác biệt giữa thư mục làm việc và chỉ mục:

    git diff
    

    Nhưng nếu bạn muốn biết sự khác biệt giữa những gì bạn đang nhập bây giờ và lần cam kết cuối cùng thì bạn thực sự đang yêu cầu sự khác biệt giữa thư mục làm việc + chỉ mục và HEAD:

    git diff HEAD
    
  • Đối với một tệp nhất định, hãy xem danh sách thay đổi đã gửi ảnh hưởng đến dòng nào -> Điều này thật dễ dàng:

    git blame filename
    

    hoặc thậm chí tốt hơn, nếu bạn đang ở trong môi trường cửa sổ:

    git gui blame filename
    

    Git gui mất nhiều thời gian hơn để phân tích cú pháp tệp (nó được viết bằng tcl thay vì C) nhưng nó có rất nhiều tính năng gọn gàng bao gồm khả năng "du hành thời gian" trở lại quá khứ bằng cách nhấp vào ID cam kết. Tôi chỉ ước họ triển khai một tính năng để "du hành thời gian" đến tương lai để tôi có thể tìm ra cách một lỗi đã cho cuối cùng sẽ được giải quyết ;-)

  • Đối với một tệp nhất định, hãy xem danh sách mô tả các danh sách thay đổi đã ảnh hưởng đến tệp -> cũng dễ dàng:

    git log filename
    

    Nhưng git log là một công cụ mạnh hơn nhiều so với chỉ này. Trên thực tế, hầu hết các tập lệnh cá nhân của tôi đều dựa vào nhật ký git để đọc kho lưu trữ. Đọc trang người đàn ông.

  • Gửi danh sách thay đổi đang chờ xử lý -> Cũng dễ dàng:

    git commit
    

Xem câu trả lời của tôi cho câu hỏi trước để xem quy trình làm việc git điển hình của tôi: Học Git. Cần biết mình có đang đi đúng hướng không

Nếu bạn tuân theo quy trình làm việc mà tôi đã vạch ra thì bạn sẽ thấy các công cụ như gitk có giá trị hơn nhiều vì nó cho phép bạn thấy rõ các nhóm thay đổi.


Câu trả lời bổ sung:

Git rất linh hoạt và có một số cách để thực hiện những gì bạn mô tả. Điều cần nhớ là luôn bắt đầu một nhánh mới cho mỗi tính năng bạn đang làm việc. Điều này có nghĩa là nhánh chính không được chạm vào vì vậy bạn luôn có thể quay lại nó để sửa lỗi. Làm việc trong git hầu như luôn bắt đầu với:

git checkout -b new-feature-a

Bây giờ bạn có thể chỉnh sửa tệp a.txt. Để làm việc đồng thời trên một tính năng khác, hãy:

git checkout master
git checkout -b new-feature-z

Bây giờ bạn có thể chỉnh sửa tệp z.txt. Để chuyển về a.txt:

git checkout new-feature-a

Nhưng chờ đã, có những thay đổi đối với new-feature-z và git sẽ không cho phép bạn chuyển các nhánh. Tại thời điểm này, bạn có hai sự lựa chọn. Cách đầu tiên là đơn giản nhất, cam kết tất cả các thay đổi đối với nhánh hiện tại:

git add .
git commit
git checkout new-feature-a

Đây là những gì tôi muốn giới thiệu. Nhưng nếu bạn thực sự chưa sẵn sàng để cam kết mã, bạn có thể tạm thời lưu trữ nó:

git stash

Bây giờ bạn có thể chuyển sang nhánh new-feature-a. Để quay lại mã bạn đang làm việc, chỉ cần bật kho lưu trữ:

git checkout new-feature-z
git stash pop

Khi tất cả hoàn tất, hãy hợp nhất tất cả các thay đổi lại thành chính:

git merge --no-ff new-feature-a
git merge --no-ff new-feature-z

Bởi vì hợp nhất rất nhanh chóng và dễ dàng (dễ dàng vì xung đột rất hiếm và việc giải quyết xung đột, khi một xảy ra, không quá khó) nên chúng tôi sử dụng các nhánh trong git cho mọi thứ.

Đây là một ví dụ khác về cách sử dụng phổ biến của các nhánh trong git mà bạn không thấy trong các công cụ kiểm soát nguồn khác (ngoại trừ có lẽ là thương mại):

Bạn cần tiếp tục thay đổi các tệp cấu hình của mình để phản ánh môi trường phát triển của bạn? Sau đó, sử dụng một nhánh:

git checkout -b dev-config

Bây giờ hãy chỉnh sửa các tệp cấu hình của bạn trong trình chỉnh sửa yêu thích của bạn, sau đó thực hiện các thay đổi:

git add .
git commit

Giờ đây, mọi nhánh mới có thể bắt đầu từ nhánh dev-config thay vì master:

git checkout dev-config
git checkout -b new-feature-branch

Sau khi bạn hoàn tất, hãy xóa các chỉnh sửa trong dev-config khỏi new-feature-branch bằng cách sử dụng rebase tương tác:

git rebase -i master

Xóa các cam kết bạn không muốn sau đó lưu lại. Bây giờ bạn có một nhánh sạch mà không cần chỉnh sửa cấu hình tùy chỉnh. Đã đến lúc hợp nhất trở lại trang cái:

git checkout master
git merge --no-ff new-feature-branch
# because master have changed, it's a good idea to rebase dev-config:
git checkout dev-config
git rebase master

Cần lưu ý rằng loại bỏ các chỉnh sửa với git rebase -ichẵn hoạt động khi tất cả các thay đổi xảy ra trong cùng một tệp. Git ghi nhớ các thay đổi chứ không phải nội dung tệp *.

* lưu ý: thực ra, về mặt kỹ thuật không hoàn toàn đúng nhưng với tư cách là người dùng thì đó là cảm giác như thế nào


Thêm câu trả lời bổ sung:

Vì vậy, từ nhận xét của bạn, có vẻ như bạn muốn có hai nhánh tồn tại đồng thời để bạn có thể kiểm tra cách mã kết hợp hoạt động. Chà, đây là một cách hay để minh họa sức mạnh và tính linh hoạt của các nhánh.

Đầu tiên, một từ ngụ ý về lịch sử phân nhánh rẻ và có thể sửa đổi trong quy trình làm việc của bạn. Khi tôi sử dụng CVS và SVN, tôi luôn có một chút miễn cưỡng khi cam kết. Đó là bởi vì việc sử dụng mã không ổn định chắc chắn sẽ làm hỏng mã làm việc của người khác. Nhưng với git, tôi đã đánh mất nỗi sợ hãi đó. Đó là bởi vì trong git, người khác sẽ không nhận được các thay đổi của tôi cho đến khi tôi hợp nhất chúng lại với nhau. Vì vậy, bây giờ tôi thấy mình cam kết mã sau mỗi 5 dòng tôi viết. Bạn không cần tầm nhìn xa hoàn hảo để cam kết. Bạn chỉ cần thay đổi suy nghĩ của mình: commit-to-branch == add-to-changeset, merge-to-master == commit-changeset.

Vì vậy, trở lại ví dụ. Đây là cách tôi sẽ làm điều đó. Giả sử bạn có một chi nhánh new-feature-zvà bạn muốn kiểm tra nó new-feature-a. Tôi chỉ cần tạo một nhánh mới để kiểm tra nó:

# assume we are currently in branch new-feature-z
# branch off this branch for testing
git checkout -b feature-z-and-feature-a
# now temporarily merge new-feature-a
git merge --no-ff new-feature-a

Bây giờ bạn có thể kiểm tra. Nếu bạn cần sửa đổi điều gì đó để làm cho feature-z hoạt động với feature-a thì hãy làm như vậy. Nếu vậy, bạn có thể hợp nhất lại các thay đổi đối với nhánh có liên quan. Sử dụng git rebase -iđể xóa các thay đổi không liên quan khỏi hợp nhất.

Ngoài ra, bạn cũng có thể sử dụng git rebase để tạm thời thay đổi cơ sở của new-feature-z để trỏ đến new-feature-a:

# assume we are currently in branch new-feature-z
git rebase new-feature-a

Bây giờ lịch sử chi nhánh được sửa đổi để new-feature-z sẽ dựa trên new-feature-a thay vì master. Bây giờ bạn có thể kiểm tra. Mọi thay đổi được cam kết trong nhánh này sẽ thuộc về nhánh new-feature-z. Nếu bạn cần sửa đổi tính năng mới-a chỉ cần chuyển trở lại nó và rebase để nhận các thay đổi mới:

git checkout new-feature-a
# edit code, add, commit etc..
git checkout new-feature-z
git rebase new-feature-a
# now new-feature-z will contain new changes from new-feature-a

Khi bạn hoàn tất, chỉ cần căn cứ lại trở lại trang chủ để xóa các thay đổi khỏi tính năng mới-a:

# assume we are currently in branch new-feature-z
git rebase master

Đừng ngại bắt đầu một chi nhánh mới. Đừng ngại bắt đầu một nhánh bỏ đi. Đừng ngại vứt bỏ cành cây. Và vì merge == submit và commit == add-to-changeset nên đừng ngại cam kết thường xuyên. Hãy nhớ rằng cam kết là công cụ hoàn tác cuối cùng của nhà phát triển.

Ồ, và một điều khác, trong git các nhánh đã xóa vẫn tồn tại trong kho lưu trữ của bạn. Vì vậy, nếu bạn đã vô tình xóa một cái gì đó mà sau này bạn nhận ra là hữu ích, bạn luôn có thể lấy lại bằng cách tìm kiếm lịch sử. Vì vậy, đừng ngại vứt bỏ cành cây.


1
Mỗi nhánh có "chỉ mục" riêng của nó, hay có một chỉ mục duy nhất được chia sẻ giữa các nhánh? Thử nghiệm của tôi dường như đề xuất cái sau, nhưng bạn nói "một git nhánh cụ thể có khái niệm về chỉ mục hoặc bộ nhớ cache" gợi ý cái trước.
Laurence Gonsalves

4
Đó là một công cụ khác. Bạn cần một quy trình làm việc khác với tư duy và thói quen khác. Không có git không hoạt động theo cách bạn mô tả. Đó là cành cây và không có gì khác. Nhưng có những công cụ thao túng nhánh rất mạnh. Tôi khuyên bạn nên coi mình là một người mới chưa biết gì về kiểm soát nguồn và đọc các hướng dẫn cơ bản. Hãy xem xét tư duy hiện tại của bạn là "bad habbit" mà bạn phải được đào tạo lại để chống lại ở git-land. Xin lỗi ..
slbetman

1
Vì vậy, bạn sẽ làm gì trong git khi bạn có hai việc bạn muốn thực hiện đồng thời (và ở cùng một nơi, vì vậy bạn có thể thử nghiệm các thay đổi chưa cam kết đối với nhau), nhưng bạn muốn cam kết chúng riêng biệt? Ngoài ra, làm cách nào bạn có thể chỉnh sửa thông báo cam kết trước khi thực hiện cam kết? Tôi có thể chấp nhận rằng quy trình làm việc khác nhau, nhưng bạn chưa nói quy trình làm việc tương đương git là gì. Nói đây là những thói quen xấu nghe có vẻ hơi khủng khiếp giống như cố gắng loại bỏ một lỗi như một tính năng.
Laurence Gonsalves

2
Đọc câu trả lời cập nhật của tôi. Bạn vẫn đang suy nghĩ về những thay đổi chưa cam kết khi bạn nên nghĩ về các nhánh chưa được hợp nhất.
slbetman

2
Câu trả lời rất rộng rãi. Điều này nên được wiki hóa vào thời điểm nào?
Tim Clemons

1

Tôi không có đủ kinh nghiệm p4 để tạo ra một bảng gian lận thực tế, nhưng có ít nhất một số điểm tương đồng để rút ra. Một "tập hợp thay đổi" p4 là một "cam kết" git.

Các thay đổi đối với không gian làm việc cục bộ của bạn được thêm vào "chỉ mục" với git addvà chỉ mục sau đó được cam kết với git commit. Vì vậy, chỉ mục là danh sách thay đổi đang chờ xử lý của bạn, cho tất cả các ý định và mục đích.

Bạn xem xét các thay đổi với git diffgit status, nơi git diffthường hiển thị các thay đổi giữa không gian làm việc và chỉ mục, nhưng git diff --cachedhiển thị các thay đổi giữa chỉ mục và kho lưu trữ (= danh sách thay đổi đang chờ xử lý của bạn).

Để biết thêm thông tin chuyên sâu, tôi khuyên bạn nên sử dụng http://progit.org/book/ . Vì bạn biết kiểm soát phiên bản nói chung, bạn có thể đọc lướt rất nhiều và trích xuất thông tin cụ thể về git ...


1
Tôi không đồng ý rằng "một bộ thay đổi p4 là một cam kết git"; chúng là những điểm tương đương gần nhất, đúng, nhưng tập hợp các thay đổi p4 gần với tập hợp các cam kết git hơn nhiều. Một tập hợp thay đổi p4 đại diện cho một tính năng, trong khi một nhánh git đại diện cho một tính năng.
RJFalconer

@RJFalconer Erm. "Chi nhánh" cũng là một chi nhánh ở Perforce, phải không? Và "tập hợp các thay đổi" là một tập hợp nguyên tử các thay đổi đối với một hoặc nhiều tệp, rất giống một cam kết? Nếu không, bạn sẽ nói p4 tương đương với commit là gì?
Jakob Borg

Tôi sẽ nói rằng p4 không có tương đương, đơn giản bởi vì mức độ nguyên tử không giống nhau; trong git, tôi có thể thực hiện một số thay đổi trong một tệp nhất định sau đó cam kết chúng trong các cam kết khác nhau (git add -p), do đó tách việc tái cấu trúc / dọn dẹp trong lịch sử khỏi tính năng / sửa lỗi. Nếu tôi làm điều này trong p4, tôi sẽ phải phát triển hai phần riêng biệt. Ngay cả khi đó các cam kết của tôi có thể không liên tục vì các nhà phát triển khác có thể gửi giữa chúng (trừ khi tôi chi nhánh riêng, liên quan đến việc sao chép không thực tế trên đĩa).
RJFalconer

Tuyên bố từ chối trách nhiệm: Tôi chỉ mới sử dụng p4 được vài tháng và rất có thể có một số tính năng của nó thực hiện được điều này mà tôi chưa xem qua.
RJFalconer

p4 changelists và các nhánh p4 về mặt logic giống như git commit và git branch. p4 giá đỡ tương đương với git stash. Điểm chúng khác nhau là ở cách triển khai (tức là phân phối so với máy khách-máy chủ) và sự khác biệt đó dẫn đến p4 tương đương với kiểm tra git bao gồm nhiều bước và thời gian đáng kể. Chi phí chung là nhiều nhánh thường được lưu trữ cục bộ trên đĩa thay vì thực hiện tương tự như kiểm tra git. kệ p4 được lưu trữ trên máy chủ thay vì trong repo cục bộ.
Josh Heitzman,

1

Tôi đau khổ như bạn với việc thiếu khái niệm "người thay đổi" không hoàn toàn giống với các nhánh git.

Tôi sẽ viết một tập lệnh nhỏ sẽ tạo một tệp danh sách thay đổi với danh sách các tệp trong danh sách thay đổi đó.

Một lệnh khác để chỉ gửi một danh sách thay đổi nhất định bằng cách chỉ cần gọi git commit -a @ change_list_contents.txt và sau đó "git commit"

Hy vọng điều đó sẽ hữu ích, Elias


Vâng, tôi đã thực sự cân nhắc làm một việc như thế này, mặc dù tại thời điểm tôi hỏi câu hỏi này, tôi chưa quen với git và vì vậy tôi muốn biết giải pháp "gốc". Bây giờ tôi thấy rằng điều chính tôi bỏ lỡ là khả năng làm việc trên một thông báo cam kết mà không thực sự cam kết. Vì vậy, có thể được giải quyết bằng cách có một tệp để giữ "thông báo cam kết đang chờ xử lý", và có lẽ một số phép thuật để tự động đọc nó khi viết thông báo cam kết.
Laurence Gonsalves

@LaurenceGonsalves, quy trình công việc tôi sử dụng là gửi các thông báo cam kết không hoàn hảo (hoặc thậm chí chỉ là "WIP") trong khi tôi tập trung vào công việc, sau đó sửa đổi sau đó trong quá trình rebase của tôi. Vì các cam kết là hoàn toàn cục bộ, chúng không cần phải là cuối cùng cho đến khi bạn cung cấp chi nhánh của mình (bằng cách đẩy nó đến điều khiển từ xa hoặc tương tự của bạn).
RJFalconer

1

Có một giải pháp thay thế nhẹ hơn trong git có thể tạo thành một phần của quy trình làm việc của bạn; sử dụng khu vực dàn git.

Tôi thường chỉ thực hiện các thay đổi sau đó gửi dưới dạng một số cam kết (ví dụ: thêm câu lệnh gỡ lỗi, cấu trúc lại, thực sự sửa một lỗi). Thay vì thiết lập danh sách thay đổi lực lượng của bạn, sau đó thực hiện thay đổi, sau đó gửi, bạn chỉ có thể thực hiện các thay đổi của mình sau đó chọn cách gửi chúng (tùy chọn sử dụng khu vực dàn dựng git).

Bạn có thể cam kết các tệp cụ thể từ dòng lệnh với:

git commit a.txt
git commit z.txt

Hoặc sắp xếp các tệp một cách rõ ràng trước tiên:

git add a.txt
git commit
git add z.txt
git commit

git gui sẽ cho phép bạn chọn các dòng hoặc phần từ bên trong tệp để tạo cam kết trong khu vực dàn dựng. Điều này rất hữu ích nếu bạn có các thay đổi trong một tệp mà bạn muốn có trong các cam kết khác nhau. Đã chuyển từ git sang perforce và đây là một điều mà tôi thực sự nhớ.

Có một lưu ý nhỏ cần ghi nhớ với quy trình làm việc này. Nếu bạn thực hiện thay đổi A và B đối với một tệp, hãy kiểm tra tệp, sau đó cam kết A thì bạn chưa kiểm tra cam kết đó (độc lập với B).


Chắc chắn đúng là git cho phép bạn thực hiện các cam kết thậm chí còn chi tiết hơn so với perforce (ví dụ: dòng và nhóm). Điều tôi (vẫn) bỏ lỡ từ perforce là khả năng để nó theo dõi mô tả thay đổi (hay còn gọi là thông báo cam kết) cho những gì tôi hiện đang làm. Ví dụ: khi tôi chuẩn bị sửa lỗi # 12345, tôi sẽ tạo một danh sách thay đổi nói rằng tôi đang làm điều đó (nhưng không gửi hoặc cam kết nó). Sau đó, khi tôi làm việc trên nó, tôi sẽ cập nhật mô tả thay đổi để cho biết những gì tôi đã làm. Cuối cùng, khi tôi hoàn thành, tôi sẽ xác nhận danh sách thay đổi.
Laurence Gonsalves

Trong git, có vẻ như tương đương thô là cam kết các bit nhỏ (thường không hoạt động) đó cho một nhánh nhà phát triển, và sau đó khi mọi thứ đã ổn thì hợp nhất các thay đổi lại. Điều này vẫn còn cảm thấy tẻ nhạt và khó hiểu hơn nhiều đối với tôi. Ngoài ra, tôi vẫn chưa thực sự quen với ý tưởng cam kết mã thậm chí không biên dịch.
Laurence Gonsalves

@LaurenceGonsalves Tò mò nếu bạn đã quen với nó trong thời gian chờ đợi. Tôi đến Perforce từ Git và tôi không thể cam kết cứ sau 15 phút, sau đó đẩy khi tôi sẵn sàng.
damian

0

Điều này không trả lời cụ thể câu hỏi của bạn, nhưng tôi không biết liệu bạn có biết rằng phiên bản perforce 2 Người dùng, 5 Workspace miễn phí để tải xuống và sử dụng từ trang web perforce hay không .

Bằng cách này, bạn có thể sử dụng lực lượng lao động tại nhà cho các dự án cá nhân của mình nếu bạn muốn. Một điều khó chịu là 5 không gian làm việc có thể hơi hạn chế, nhưng thật đáng kinh ngạc khi có sẵn lực lượng để sử dụng tại nhà.


2
Đó là những gì tôi đang làm, nhưng tôi muốn chuyển sang thứ gì đó mã nguồn mở và cũng được sử dụng bởi các dự án mã nguồn mở.
Laurence Gonsalves 10/09/10

0

Đã sử dụng khá rộng rãi cả Perforce và git, chỉ có một cách tôi có thể thấy để đến bất kỳ đâu gần các danh sách thay đổi Perforce bằng git.

Điều đầu tiên cần hiểu là để triển khai chính xác chức năng này trong git theo cách mà nó không phải là một kluge hoàn chỉnh, ví dụ: cố gắng đánh bóng nó vào các nhánh, sẽ yêu cầu thay đổi sau: git sẽ yêu cầu nhiều vùng dàn cho một nhánh duy nhất .

Perforce thay đổi cho phép một quy trình làm việc đơn giản là không có tương đương trong git. Hãy xem xét quy trình làm việc sau:

Check out a branch
Modify file A and add it to changelist 1
Modify file B and add it to changelist 2

Nếu bạn cố gắng thực hiện việc này bằng cách sử dụng các nhánh trong git, bạn sẽ có hai nhánh, một nhánh có các thay đổi đối với tệp A, nhánh kia có các thay đổi đối với tệp B, nhưng không có nơi nào bạn có thể thấy các thay đổi đối với cả hai tệp ABtại cùng lúc.

Giá trị gần đúng nhất mà tôi có thể thấy là sử dụng git add . -pvà sau đó sử dụng 'a''d' lệnh phụ để chọn hoặc từ chối toàn bộ tệp. Tuy nhiên, điều đó không hoàn toàn giống nhau, và sự khác biệt ở đây bắt nguồn từ sự khác biệt cơ bản trong toán hạng mô thức chung của hai hệ thống.

Git (và lật đổ, không phải vấn đề quan trọng đối với cuộc thảo luận này) cho phép thay đổi tệp mà không cần thông báo cho bất kỳ ai về điều này trước thời hạn. Bạn chỉ cần thay đổi một tệp, và sau đó để git sắp xếp tất cả khi bạn thực hiện các thay đổi. Perforce yêu cầu bạn chủ động kiểm tra tệp trước khi cho phép thay đổi và chính vì lý do này mà các danh sách thay đổi phải tồn tại. Về bản chất, Perforce yêu cầu bạn thêm một tệp vào chỉ mục trước khi thay đổi nó. Do đó, sự cần thiết của nhiều danh sách thay đổi trong Perforce, và cũng là lý do tại sao git không có tương đương. Nó chỉ đơn giản là không cần chúng.


0

Với Git 2.27 (Quý 2 năm 2020), " git p4" đã học được bốn móc mới và cũng có --no-verifytùy chọn "" để bỏ qua chúng (và " p4-pre-submit" móc hiện có ).

Xem cam kết 1ec4a0a , cam kết 38ecf75 , cam kết cd1e0dc (14 tháng 2 năm 2020) và cam kết 4935c45 , cam kết aa8b766 , cam kết 9f59ca4 , cam kết 6b602a2 (11 tháng 2 năm 2020) bởi Ben Keene ( seraphire) .
(Được hợp nhất bởi Junio ​​C Hamano - gitster- trong cam kết 5f2ec21 , ngày 22 tháng 4 năm 2020)

git-p4: thêm móc gửi p4

Ký tên: Ben Keene

Lệnh git "commit " hỗ trợ một số hook hỗ trợ thay đổi hành vi của lệnh commit.

Các git-p4.pychương trình chỉ có một móc hiện có, " p4-pre-submit".

Lệnh này xuất hiện sớm trong quá trình.

Không có móc nào trong quy trình sửa đổi văn bản danh sách thay đổi P4 theo chương trình.

Thêm 3 móc mới vào git-p4.pytùy chọn gửi.

Các móc mới là:

  • p4-prepare-changelist- Thực hiện hook này sau khi tệp danh sách thay đổi đã được tạo.
    Móc sẽ được thực hiện ngay cả khi --prepare-p4-onlytùy chọn được đặt.
    Hook này bỏ qua --no-verifytùy chọn để phù hợp với hành vi hiện có của git commit.

  • p4-changelist- Thực hiện hook này sau khi người dùng đã chỉnh sửa danh sách thay đổi.
    Không thực hiện hook này nếu người dùng đã chọn --prepare-p4-onlytùy chọn.
    Cái móc này sẽ tôn trọng --no-verify, tuân theo các quy ước của git commit.

  • p4-post-changelist- Thực hiện hook này sau khi quá trình gửi P4 đã hoàn tất thành công.
    Móc này không có tham số và được thực thi bất kể --no-verifytùy chọn nào.

Giá trị trả về của nó sẽ không được kiểm tra.

Các cuộc gọi đến các móc mới: p4-prepare-changelist, p4-changelist, và p4-post-changelisttất cả nên được gọi là bên trong khối try-cuối cùng.


Trước Git 2.28 (Quý 3 năm 2020), --prepare-p4-onlytùy chọn "" được cho là dừng sau khi phát lại một tập thay đổi, nhưng vẫn tiếp tục (do nhầm lẫn?)

Xem cam kết 2dfdd70 (12 tháng 5 năm 2020) bởi Ben Keene ( seraphire) .
(Được hợp nhất bởi Junio ​​C Hamano - gitster- trong cam kết 7a8fec9 , 02/06/2020)

git-p4.py: sửa --prepare-p4-onlylỗi với nhiều cam kết

Ký tên: Ben Keene

Khi sử dụng git p4 submitvới --prepare-p4-onlytùy chọn, chương trình nên chuẩn bị một danh sách thay đổi p4 duy nhất và thông báo cho người dùng rằng nhiều cam kết hơn đang chờ xử lý và sau đó dừng xử lý.

Một lỗi đã được đưa ra bởi p4-changelisttính năng hook khiến chương trình tiếp tục thử và xử lý tất cả các danh sách thay đổi đang chờ xử lý cùng một lúc.

Hàm applyCommittrả về Truekhi áp dụng cam kết thành công và chương trình sẽ tiếp tục.
Tuy nhiên, khi cờ tùy chọn--prepare-p4-only được đặt, chương trình sẽ dừng sau ứng dụng đầu tiên.

Thay đổi logic trong phương thức chạy cho P4Submit để kiểm tra cờ --prepare-p4-onlysau khi hoàn tất thành công applyCommitphương thức.

Nếu có nhiều hơn 1 cam kết đang chờ gửi tới P4, phương thức sẽ chuẩn bị đúng cách danh sách thay đổi P4, tuy nhiên, nó vẫn sẽ thoát khỏi ứng dụng với mã xuất là 1.

Các tài liệu hiện hành không định nghĩa những gì mã lối ra phải ở trong tình trạng này.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.