Làm cách nào để sử dụng Git cho điều khiển nguồn Unity3D?


499

Thực tiễn tốt nhất để sử dụng kiểm soát nguồn Git với Unity 3D, đặc biệt là trong việc xử lý bản chất nhị phân của các dự án Unity 3D là gì? Vui lòng mô tả quy trình công việc, những đường dẫn nào sẽ được bao gồm trong .gitignore, cài đặt nào sẽ được đặt trong Unity và / hoặc dự án và bất kỳ điều đặc biệt nào khác cần lưu ý.

Lưu ý: Tôi nhận ra rằng sử dụng Máy chủ tài sản là cách được Unity khuyên dùng, nhưng tôi muốn sử dụng Git vì nhiều lý do. Xin vui lòng không có câu trả lời rằng tiểu bang hoặc lập luận rằng tôi chỉ nên sử dụng Máy chủ tài sản. Máy chủ tài sản thực sự không phải là một lựa chọn cho tôi.


3
"chỉ sử dụng svn" bất kể đối số sit git V vô nghĩa, git chỉ không dành cho các tệp nhị phân lớn. các dự án thống nhất là các bộ phim (và các tệp nhị phân khổng lồ khác nhau - kết cấu, v.v.), với một số dòng mã. bạn sẽ sử dụng git để lưu trữ bộ sưu tập phim của bạn? svn ít nhất là hợp lý.
Fattie

1
Giải pháp đơn giản nhất là chỉ cần loại trừ tất cả các thư mục nhị phân bằng gitignore và chỉ sử dụng git cho các tệp mã thực tế của bạn và có lẽ các tệp tài sản của bạn. Tất cả các nhị phân không cần được đưa vào vì mọi thành viên trong nhóm có thể tự biên dịch chúng?
Kokodoko

Các nghệ sĩ @Kokodoko không thể biên dịch các tệp thực thi của riêng họ.
Crashworks

Ngay cả khi đó là sự thật, họ vẫn có thể đẩy tài sản hình ảnh mới lên ... để các nhà phát triển có thể biên dịch với tác phẩm nghệ thuật mới ...
Kokodoko

@Kokodoko Điều đó có nghĩa là một nghệ sĩ sẽ cần đợi một nhà phát triển để xem cam kết và thực hiện một bản dựng để xem những thay đổi của họ trong trò chơi. Đó là một thời gian lặp rất dài.
Crashworks

Câu trả lời:


522

Sau đây là một đoạn trích từ blog cá nhân của tôi .

Sử dụng Git với các trò chơi 3D

Cập nhật tháng 10 năm 2015: GitHub đã phát hành một plugin cho Git có tên Git LFS trực tiếp giải quyết vấn đề dưới đây. Bây giờ bạn có thể dễ dàng và hiệu quả phiên bản các tệp nhị phân lớn!

Git có thể hoạt động tốt với các trò chơi 3D. Tuy nhiên, lưu ý chính ở đây là việc tạo các tệp phương tiện lớn (> 5 MB) có thể là một vấn đề trong thời gian dài khi lịch sử cam kết của bạn phình to. Chúng tôi đã giải quyết vấn đề tiềm năng này trong các dự án của mình bằng cách chỉ phiên bản tài sản nhị phân khi nó được coi là cuối cùng. Nghệ sĩ 3D của chúng tôi sử dụng Dropbox để làm việc trên tài sản WIP, cả hai vì lý do trên và bởi vì nó là nhiều nhanh hơn và đơn giản hơn (không nhiều nghệ sĩ sẽ chủ động muốn sử dụng Git!).

Quy trình làm việc của Git

Quy trình làm việc Git của bạn là rất nhiều thứ bạn cần để tự quyết định dựa trên kinh nghiệm của bản thân với tư cách là một nhóm và cách bạn làm việc cùng nhau. Tuy nhiên. Tôi rất muốn giới thiệu phương pháp Git Flow được đặt tên thích hợp như được mô tả bởi tác giả gốc ở đây .

Tôi sẽ không đi sâu vào quá nhiều về cách thức phương pháp này hoạt động vì tác giả đã mô tả nó một cách hoàn hảo và cũng khá ít từ để dễ dàng vượt qua. Bây giờ tôi đã sử dụng với nhóm của mình một thời gian và đó là quy trình làm việc tốt nhất mà chúng tôi đã thử cho đến nay.

Ứng dụng khách Git GUI

Đây thực sự là một sở thích cá nhân ở đây vì có khá nhiều tùy chọn về GUI Git hoặc liệu có nên sử dụng GUI hay không. Nhưng tôi muốn đề xuất ứng dụng SourceTree miễn phí vì nó cắm hoàn hảo với tiện ích mở rộng Git Flow. Đọc hướng dẫn SourceTree ở đây về việc triển khai phương pháp Git Flow trong ứng dụng của họ.

Unity3D Bỏ qua các thư mục

Để kiểm tra phiên bản cập nhật, Github duy trì tệp Unity.gitignore mà không có thông tin cụ thể về hệ điều hành.

# =============== #
# Unity generated #
# =============== #
Temp/
Library/

# ===================================== #
# Visual Studio / MonoDevelop generated #
# ===================================== #
ExportedObj/
obj/
*.svd
*.userprefs
/*.csproj
*.pidb
*.suo
/*.sln
*.user
*.unityproj
*.booproj

# ============ #
# OS generated #
# ============ #
.DS_Store
.DS_Store?
._*
.Spotlight-V100
.Trashes
ehthumbs.db
Thumbs.db

Cài đặt Unity3D

Đối với các phiên bản Unity 3D v4.3 trở lên:

  1. (Bỏ qua bước này trong v4.5 trở lên) Bật Externaltùy chọn trong Unity → Preferences → Packages → Repository.
  2. Mở Editmenu và chọn Project Settings → Editor:
    1. Chuyển Version Control Modetới Visible Meta Files.
    2. Chuyển Asset Serialization Modetới Force Text.
  3. Lưu cảnh và dự án từ Filemenu.

Bạn muốn di chuyển repo hiện tại của bạn sang LFS?

Kiểm tra bài viết trên blog của tôi để biết các bước về cách làm điều đó ở đây .

Cấu hình bổ sung

Một trong những phiền toái lớn mà người ta gặp phải khi sử dụng Git với các dự án Unity3D là Git không quan tâm đến các thư mục và sẽ vui vẻ để lại các thư mục trống xung quanh sau khi xóa các tệp khỏi chúng. Unity3D sẽ tạo các tệp * .meta cho các thư mục này và có thể gây ra một chút trận chiến giữa các thành viên trong nhóm khi Git cam kết tiếp tục thêm và xóa các tệp meta này.

Thêm hook sau hợp nhất Git này vào /.git/hooks/thư mục để lưu trữ với các dự án Unity3D trong đó. Sau bất kỳ thao tác kéo / hợp nhất Git nào, nó sẽ xem xét các tệp nào đã bị xóa, kiểm tra xem thư mục mà nó tồn tại có trống không và nếu vậy hãy xóa nó.


2
Đề cập đến quy trình công việc git là tốt, nhưng có lẽ tôi nên làm rõ trong câu hỏi của mình, tôi đang hỏi về quy trình công việc đặc biệt cụ thể cho sự thống nhất 3D. Như bạn có thể biết, các dự án thống nhất chủ yếu dựa vào các tệp nhị phân. Có bất kỳ cân nhắc đặc biệt để đối phó với điều này? Một số khuyến nghị tôi tìm thấy khi nghiên cứu chủ đề này là sử dụng quy trình công việc tránh sáp nhập càng nhiều càng tốt. Có lẽ bạn không chia sẻ trong tình cảm này, nhưng câu hỏi của tôi cụ thể hơn đối với các vấn đề cụ thể của unity3d hơn là các ưu tiên quy trình công việc chung.
Nhấn vào

3
Chúng tôi sử dụng một phụ lục git để quản lý nội dung nhị phân lớn của chúng tôi. Hỗ trợ Windows không phải là tuyệt vời nhưng nó đang trở nên tốt hơn. Điều này chỉ hữu ích nếu bạn không quan tâm đến việc theo dõi vòng quay trong các tệp nhị phân lớn.
Jerdak

2
Một bản cập nhật cho điều này - chúng tôi đã thử thiết lập của bạn và nó hoạt động khá tốt, nhưng chúng tôi muốn tài sản của chúng tôi được tự động đồng bộ hóa. Bây giờ chúng tôi sử dụng sugarsync để đồng bộ hóa có chọn lọc thư mục tài sản nhị phân. Dropbox sẽ chỉ đồng bộ thư mục dropbox, nhưng với đồng bộ hóa đường, bạn có thể tùy ý đồng bộ hóa các thư mục ở bất cứ đâu trên ổ cứng cực kỳ hữu ích. Chúng tôi đã phải thay đổi cấu trúc thư mục Tài sản một chút để xác định một thư mục con cho các tệp nhị phân lớn này, nhưng cho đến nay nó đã hoạt động rất tốt. Chúng tôi chỉ .gitignore thư mục đó và cho phép đồng bộ hóa đường để giữ cho nó đồng bộ hóa.
Nhấn vào

2
Tại sao sự lựa chọn để đi với Hidden Meta Files?
Slipp D. Thompson

2
Đã sửa lỗi bản sao của tôi và dán lỗi đánh máy - Có, nó phải là Tệp Hiển thị.
S.Richmond

60

Trong Unity 4.3, bạn cũng phải bật tùy chọn Bên ngoài từ tùy chọn, nhưng vì Unity 4.5 nên họ đã bỏ tùy chọn đó, vì vậy quy trình thiết lập đầy đủ trông như sau:

  1. Chuyển sang Visible Meta FilestrongEditor → Project Settings → Editor → Version Control Mode
  2. Chuyển sang Force TexttrongEditor → Project Settings → Editor → Asset Serialization Mode
  3. Lưu cảnh và dự án từ Filemenu

Ngoài ra nhóm của chúng tôi đang sử dụng .gitignoretệp mở rộng hơn một chút :

# =============== #
# Unity generated #
# =============== #
Temp/
Library/

# ===================================== #
# Visual Studio / MonoDevelop generated #
# ===================================== #
ExportedObj/
obj/
*.svd
*.userprefs
/*.csproj
*.pidb
*.suo
/*.sln
*.user
*.unityproj
*.booproj

# ============ #
# OS generated #
# ============ #
.DS_Store
.DS_Store?
._*
.Spotlight-V100
.Trashes
ehthumbs.db
Thumbs.db

Lưu ý rằng các thư mục duy nhất bạn cần giữ dưới sự kiểm soát nguồn là AssetsProjectSettings.

Thông tin thêm về việc giữ Unity Project dưới sự kiểm soát nguồn bạn có thể tìm thấy trong bài viết này .


Có thể tốt hơn nếu bạn chỉnh sửa câu trả lời của tôi ở đầu để bao gồm các tùy chọn mới này. :)
S.Richmond

6
Tại sao sự lựa chọn để đi với Hidden Meta Files?
Slipp D. Thompson

Điểm một là rõ ràng sai. Không có sự thống nhất → Tùy chọn → Gói → Kho lưu trữ
Agostino

1
theo docs.unity3d.com/Manual/, nó phải là các tệp Meta hiển thị
Markus

1
Hoạt động tốt cho nhóm của tôi. Cảm ơn rât nhiều.
eifersucht

34

GIT là gì?

Git là một hệ thống kiểm soát phiên bản phân tán mã nguồn mở và miễn phí (SCM) được phát triển bởi Linus Torvalds vào năm 2005 (người sáng lập hệ điều hành Linux). Nó được tạo ra để kiểm soát mọi thứ từ các dự án từ nhỏ đến lớn với tốc độ và hiệu quả. Các công ty hàng đầu như Google, Facebook, Microsoft sử dụng GIT hàng ngày.

Nếu bạn muốn tìm hiểu thêm về GIT, hãy xem Hướng dẫn nhanh này ,

Trước hết, hãy đảm bảo bạn đã thiết lập môi trường Git của mình. Bạn cần thiết lập cả môi trường cục bộ và kho lưu trữ Git (tôi thích Github.com).

Ứng dụng khách GIT Mac / Windows

Đối với ứng dụng khách GIT gui, tôi khuyên bạn nên truy cập Github.com,

GitHub là nơi chia sẻ mã với bạn bè, đồng nghiệp, bạn cùng lớp và những người hoàn toàn xa lạ. Hơn năm triệu người sử dụng GitHub để cùng nhau xây dựng những điều tuyệt vời.

Cài đặt Unity3d

Bạn cần thực hiện các cài đặt này

Chuyển sang Tệp Meta có thể nhìn thấy trong Chỉnh sửa → Cài đặt dự án → Trình chỉnh sửa → Chế độ kiểm soát phiên bản.

nhập mô tả hình ảnh ở đây

Bật tùy chọn bên ngoài trong Unity → Tùy chọn → Gói → Kho lưu trữ

nhập mô tả hình ảnh ở đây

Chuyển sang Buộc văn bản trong Chỉnh sửa → Cài đặt dự án → Trình chỉnh sửa → Chế độ tuần tự hóa tài sản.

nhập mô tả hình ảnh ở đây

Nguồn: Sử dụng Git với điều khiển nguồn trò chơi 3D


6
+1 Câu trả lời này đã được viết ở trên nhưng câu trả lời @NabeelSaleem đã giúp tôi với những hình ảnh anh ấy cung cấp và hướng dẫn rõ ràng :) cảm ơn
aflatoon

3
Tôi không thể tìm thấy Preferences > Packagestrong Unity 5.x Bình thường? ty
Yves Lange

5
@NabeelSaleem có. Thật ra bước này trong Unity 5.x là không cần thiết. ty
Yves Lange

22

Để thêm vào mọi thứ đã nêu, cũng lý tưởng khi sử dụng git lfs với Unity. Tôi đã sử dụng nó kể từ khi nó ra đời và tôi không gặp rắc rối với nó.

Bạn sẽ muốn thêm cái này .gitattributesbên cạnh .gitignoretập tin của bạn

*.cs diff=csharp text
*.cginc text
*.shader text

*.mat merge=unityyamlmerge eol=lf
*.anim merge=unityyamlmerge eol=lf
*.unity merge=unityyamlmerge eol=lf
*.prefab merge=unityyamlmerge eol=lf
*.physicsMaterial2D merge=unityyamlmerge eol=lf
*.physicsMaterial merge=unityyamlmerge eol=lf
*.asset merge=unityyamlmerge eol=lf
*.meta merge=unityyamlmerge eol=lf
*.controller merge=unityyamlmerge eol=lf

*.a filter=lfs diff=lfs merge=lfs -text
*.mp3 filter=lfs diff=lfs merge=lfs -text
*.wav filter=lfs diff=lfs merge=lfs -text
*.aif filter=lfs diff=lfs merge=lfs -text
*.ttf filter=lfs diff=lfs merge=lfs -text
*.png filter=lfs diff=lfs merge=lfs -text
*.jpg filter=lfs diff=lfs merge=lfs -text
*.exr filter=lfs diff=lfs merge=lfs -text
*.fbx filter=lfs diff=lfs merge=lfs -text
*.FBX filter=lfs diff=lfs merge=lfs -text
*.rns filter=lfs diff=lfs merge=lfs -text
*.reason filter=lfs diff=lfs merge=lfs -text
*.lxo filter=lfs diff=lfs merge=lfs -text

Đó là danh sách tập tin cán của tôi. Nếu bạn sử dụng các tệp nhị phân bổ sung không được liệt kê, hãy thêm chúng.

Tôi cũng có các tập tin được cấu hình để sử dụng yamlmerge, bạn sẽ cần phải thiết lập điều này. Bạn có thể đọc về nó ở đây: http://docs.unity3d.com/Manual/SmartMerge.html


11

Bây giờ chúng tôi có tích hợp liền mạch để thống nhất với tiện ích mở rộng Github to Unity ... https://unity.github.com/

Tiện ích mở rộng GitHub cho Unity mới mang lại luồng công việc GitHub và hơn thế nữa cho Unity, cung cấp hỗ trợ cho các tệp lớn với Git LFS và khóa tệp.

Tại thời điểm viết dự án là bản alpha, nhưng vẫn có thể sử dụng cho các dự án cá nhân.


bạn đã thử cái này chưa?
Nabeel K

11

Tôi nghĩ rằng tôi có thể đăng một đơn giản hơn .gitignorecho bất cứ ai quan tâm:

# Ignore Everything
/*

# Except for these:
!/.gitignore
!/Assets
!/Packages
!/ProjectSettings

7
Một lần nữa, tất cả những câu trả lời này khá lỗi thời trên trang này. nếu vì lý do nào đó bạn phải sử dụng git với Unity, github.com/github/gitignore/blob/master/Unity.gitignore
Fattie 16/2/2016

Nhỏ, đơn giản và hoàn toàn tương thích với tất cả các phiên bản: Tôi thấy kịch bản này hoạt động tốt nhất, ngay cả đối với Unity 2017 và 2018 gần đây đã thay đổi cấu trúc dự án của họ ( UnityPackageManager/Packages/).
Isaak Eriksson

8

Những điều chính cần nhớ khi sử dụng git để kiểm soát phiên bản mã nguồn unity-3d:

(A) KHÔNG đăng ký trong thư mục Thư viện . Tôi đã phạm sai lầm này nhiều lần trong quá khứ và đã chịu đựng nó! Xóa HOẶC di chuyển thư mục thư viện trước khi thêm dự án / tệp của bạn vào git.

(B) Sử dụng "Tệp Meta Visible" - cho các phiên bản thống nhất mới nhất - 5.3.4 trở lên, điều này xảy ra theo mặc định. Đối với một số phiên bản trước đó, bạn cần thay đổi cài đặt trong: Chỉnh sửa-> Cài đặt dự án-> Kiểm soát phiên bản

(C) Sử dụng tệp .gitignore cho Unity- để đảm bảo duy trì sự tỉnh táo và các tệp không được thêm một cách không cần thiết - nếu trên android / tizen - hãy thêm quy tắc để loại trừ các tệp APK và TPK khỏi kho lưu trữ. Google tìm kiếm tệp .gitignore cho sự thống nhất HOẶC người khác sử dụng mô hình này .gitignore cho Unity do GitHub cung cấp: https://github.com/github/gitignore/blob/master/Unity.gitignore

(D) Đảm bảo tệp .gitignore được thêm vào kho lưu trữ dưới dạng tệp đầu tiên được thêm vào - bởi vì trước đây cá nhân tôi đã bỏ lỡ việc thêm tệp .gitignore. Có nhiều suy nghĩ về lý do tại sao điều này xảy ra - nhưng ngày nay tôi chỉ sao chép và thêm tệp .gitignore như bước đầu tiên của việc thiết lập kho lưu trữ.

Vì vậy, ... để làm cho một dự án Unity sẵn sàng cho git, hãy làm như sau:

(1) Chuyển đến thư mục dự án

(2) Gõ init.

(3) Sao chép tệp .gitignore: Trên MacOS: cp ~ / Tải xuống / .gitignore Trên Windows: sao chép c: \ Users [yourusername] \ Downloader.gitignore.

(4) git thêm .gitignore

(5) thêm git *

Hy vọng điều này sẽ giúp ... tất cả những điều tốt nhất!


6

Edit -> Project Settings -> Editor

Đặt Kiểm soát phiên bản thành tệp meta. Đặt tuần tự hóa tài sản để buộc văn bản.

Tôi nghĩ rằng đây là những gì bạn muốn.


1
Và sau đó, làm thế nào để bạn thiết lập hợp nhất YAML?
shinzou


6

Bạn có thể sử dụng Github cho Unity , tiện ích mở rộng Unity mang luồng công việc git vào UI của Unity.

Github cho Unity vừa phát hành phiên bản 1.0 của tiện ích mở rộng.


5

Chỉ các thư mục Tài sảnProjectS Settings cần được kiểm soát phiên bản git.

Bạn có thể làm một gitignore như thế này.

[Ll]ibrary/
[Tt]emp/
[Oo]bj/

# Autogenerated VS/MD solution and project files
*.csproj
*.unityproj
*.sln
*.suo
*.userprefs

# Mac
.DS_Store
*.swp
*.swo

Thumbs.db
Thumbs.db.meta

.vs/

3

Unity cũng cung cấp kiểm soát phiên bản nguồn riêng của mình. trước unity5 nó là unityAsset Server nhưng bây giờ nó không dùng nữa. và khởi chạy một hệ thống kiểm soát SVN mới có tên là unity collab. Nhưng vấn đề chính là sử dụng sự thống nhất và bất kỳ SVN nào đang cam kết và hợp nhất cảnh. nhưng Non của svn cho chúng ta cách giải quyết loại xung đột hoặc hợp nhất cảnh này. vì vậy phụ thuộc vào bạn mà SVN mà bạn quen thuộc. Tôi đang sử dụng công cụ SmartSVN trên Mac. và rùa trên cửa sổ.

nhập mô tả hình ảnh ở đây


1

Chỉ cần thêm vào subjet của Gitignore. Cách được đề xuất chỉ bỏ qua Thư viện và Temp, nếu gốc của dự án git của bạn. nếu bạn giống tôi và đôi khi cần dự án thống nhất là một phần của repo, chứ không phải toàn bộ repo, các chuỗi chính xác trong gitignore sẽ là:

**/[Tt]emp
**/[Ll]ibrary
**/[Bb]uild

0

Tôi muốn thêm một quy trình làm việc rất đơn giản từ một người đã thất vọng với git trong quá khứ. Có một số cách để sử dụng git, có lẽ phổ biến nhất cho sự thống nhất là GitHub Desktop, Git Bash và GitHub Unity

https://assetstore.unity.com/packages/tools/version-control/github-for-unity-118069 .

Về cơ bản tất cả họ đều làm điều tương tự nhưng sự lựa chọn của người dùng. Bạn có thể có git để thiết lập tệp lớn, cho phép lưu trữ tệp lớn miễn phí 1 GB với dung lượng lưu trữ bổ sung có sẵn trong các gói dữ liệu với giá 4 đô la / tháng cho 50 GB và điều này sẽ cho phép bạn đẩy các tệp> 100mb sang kho lưu trữ từ xa (nó lưu trữ các tệp thực tế trên một máy chủ và trong repo của bạn một con trỏ)

https://git-lfs.github.com/

Nếu bạn không muốn thiết lập lfs vì bất kỳ lý do gì, bạn có thể quét các dự án của mình cho các tệp> 128 mb trong cửa sổ bằng cách nhập kích thước: lớn trong thư mục nơi bạn có dự án của mình. Điều này có thể thuận tiện để tìm kiếm các tệp lớn, mặc dù có thể có một số tệp trong khoảng từ 100mb đến 128mb bị bỏ lỡ.

nhập mô tả hình ảnh ở đây

Định dạng chung của git bash là

git thêm. (thêm các tệp được cam kết)

git commit -m 'message' (cam kết các tệp với một tin nhắn, chúng vẫn ở trên máy tính của bạn chứ không phải trong repo từ xa, về cơ bản chúng đã được 'phiên bản' như một cam kết mới)

git đẩy (đẩy tập tin vào kho lưu trữ)

Nhược điểm của git bash cho các dự án thống nhất là nếu có tệp> 100mb, bạn sẽ không gặp lỗi cho đến khi bạn đẩy. Sau đó, bạn phải hoàn tác cam kết của mình bằng cách đặt lại đầu của bạn vào cam kết trước đó. Loại rắc rối, đặc biệt nếu bạn là người mới với git bash.

Ưu điểm của GitHub Desktop là TRƯỚC KHI bạn cam kết các tệp với 100mb, nó sẽ cung cấp cho bạn một thông báo lỗi bật lên. Sau đó, bạn có thể thu nhỏ các tệp đó hoặc thêm chúng vào tệp .gitignore.

Để sử dụng tệp .gitignore, hãy tạo một tệp có tên .gitignore trong thư mục gốc của kho lưu trữ cục bộ của bạn. Chỉ cần thêm các tệp một dòng tại một thời điểm bạn muốn bỏ qua. SharedAssets và các tệp thư mục không phải là Tài sản khác thường có thể được bỏ qua và sẽ tự động phục hồi trong trình chỉnh sửa (các gói có thể được nhập lại, v.v.). Bạn cũng có thể sử dụng ký tự đại diện để loại trừ các loại tệp.

Nếu người khác đang sử dụng repo GitHub của bạn và bạn muốn sao chép hoặc kéo, bạn cũng có sẵn các tùy chọn đó trên máy tính để bàn GitHub hoặc Git bash.

Tôi không đề cập nhiều về gói Unity GitHub nơi bạn có thể sử dụng GitHub trong trình chỉnh sửa vì cá nhân tôi không thấy giao diện rất hữu ích và tôi không nghĩ rằng nó sẽ giúp mọi người làm quen với git, nhưng đây chỉ là của tôi ưu tiên.

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.