diff --git a/external/book/content/book/fa/v2/Customizing-Git-An-Example-Git-Enforced-Policy.html b/external/book/content/book/fa/v2/Customizing-Git-An-Example-Git-Enforced-Policy.html index e9ec5d23be..da1573b232 100644 --- a/external/book/content/book/fa/v2/Customizing-Git-An-Example-Git-Enforced-Policy.html +++ b/external/book/content/book/fa/v2/Customizing-Git-An-Example-Git-Enforced-Policy.html @@ -17,42 +17,50 @@ next: book/fa/v2/Customizing-Git-Summary title: Git - An Example Git-Enforced Policy --- -

An Example Git-Enforced Policy

-
-

-In this section, you’ll use what you’ve learned to establish a Git workflow that checks for a custom commit message format, and allows only certain users to modify certain subdirectories in a project. -You’ll build client scripts that help the developer know if their push will be rejected and server scripts that actually enforce the policies.

-
-
-

The scripts we’ll show are written in Ruby; partly because of our intellectual inertia, but also because Ruby is easy to read, even if you can’t necessarily write it. -However, any language will work – all the sample hook scripts distributed with Git are in either Perl or Bash, so you can also see plenty of examples of hooks in those languages by looking at the samples.

-
-
-

Server-Side Hook

-
-

All the server-side work will go into the update file in your hooks directory. -The update hook runs once per branch being pushed and takes three arguments:

-
-
- -
-
-

You also have access to the user doing the pushing if the push is being run over SSH. -If you’ve allowed everyone to connect with a single user (like “git”) via public-key authentication, you may have to give that user a shell wrapper that determines which user is connecting based on the public key, and set an environment variable accordingly. -Here we’ll assume the connecting user is in the $USER environment variable, so your update script begins by gathering all the information you need:

-
-
-
+
+

یک مثال از سیاست‌های تحمیلی گیت

+
+

+ در این بخش، شما از آنچه که آموخته‌اید برای ایجاد یک جریان کاری گیت استفاده خواهید کرد که فرمت خاصی برای پیام‌های + کامیت را بررسی می‌کند و اجازه می‌دهد تنها کاربران خاصی به تغییر زیرپوشه‌های خاصی در یک پروژه دسترسی داشته باشند. + شما اسکریپت‌های کلاینتی خواهید ساخت که به توسعه‌دهنده کمک می‌کند تا بداند آیا ارسال آن‌ها رد خواهد شد و + اسکریپت‌های سروری که واقعاً سیاست‌ها را تحمیل می‌کنند.

+
+
+

اسکریپت‌هایی که نشان خواهیم داد به زبان روبی نوشته شده‌اند؛ بخشی به دلیل تنبلی فکری ما، اما همچنین به این دلیل که + روبی خواندنش آسان است، حتی اگر نتوانید لزوماً آن را بنویسید. + با این حال، هر زبانی کار می‌کند – تمام اسکریپت‌های نمونه هوک توزیع شده با گیت یا به زبان پرل یا بش هستند، بنابراین + می‌توانید نمونه‌های زیادی از هوک‌ها در آن زبان‌ها را با نگاه کردن به نمونه‌ها ببینید.

+
+
+

هوک سمت سرور

+
+

تمام کارهای سمت سرور در فایل update در دایرکتوری hooks شما قرار خواهد گرفت. + هوک update یک بار برای هر شاخه‌ای که به آن ارسال می‌شود اجرا می‌شود و سه آرگومان می‌گیرد:

+
+
+
    +
  • +

    نام مرجع‌ای که به آن ارسال می‌شود

    +
  • +
  • +

    نسخه قدیمی که آن شاخه بود

    +
  • +
  • +

    نسخه جدیدی که ارسال می‌شود

    +
  • +
+
+
+

شما همچنین به کاربری که در حال ارسال است دسترسی دارید اگر ارسال از طریق SSH انجام شود. + اگر به همه اجازه داده‌اید که با یک کاربر واحد (مانند "git") از طریق احراز هویت کلید عمومی متصل شوند، ممکن است + مجبور شوید که آن کاربر را به یک پوشش شل بدهید که تعیین کند کدام کاربر بر اساس کلید عمومی متصل می‌شود و یک متغیر + محیطی را به‌طور مناسب تنظیم کند. + در اینجا فرض می‌کنیم که کاربر متصل در متغیر محیطی $USER قرار دارد، بنابراین اسکریپت به‌روزرسانی شما + با جمع‌آوری تمام اطلاعاتی که نیاز دارید آغاز می‌شود:

+
+
+
#!/usr/bin/env ruby
 
 $refname = ARGV[0]
@@ -60,125 +68,147 @@ 

Server-Side Hook

$newrev = ARGV[2] $user = ENV['USER'] -puts "Enforcing Policies..." +puts "تحمیل سیاست‌ها..." puts "(#{$refname}) (#{$oldrev[0,6]}) (#{$newrev[0,6]})"
-
-
-
-

Yes, those are global variables. -Don’t judge – it’s easier to demonstrate this way.

-
-
-

Enforcing a Specific Commit-Message Format

-
-

Your first challenge is to enforce that each commit message adheres to a particular format. -Just to have a target, assume that each message has to include a string that looks like “ref: 1234” because you want each commit to link to a work item in your ticketing system. -You must look at each commit being pushed up, see if that string is in the commit message, and, if the string is absent from any of the commits, exit non-zero so the push is rejected.

-
-
-

You can get a list of the SHA-1 values of all the commits that are being pushed by taking the $newrev and $oldrev values and passing them to a Git plumbing command called git rev-list. -This is basically the git log command, but by default it prints out only the SHA-1 values and no other information. -So, to get a list of all the commit SHA-1s introduced between one commit SHA-1 and another, you can run something like this:

-
-
-
+
+
+
+

بله، این‌ها متغیرهای جهانی هستند. + قضاوت نکنید – این روش آسان‌تر برای نشان دادن است.

+
+
+

تحمیل فرمت خاص پیام کامیت

+
+

چالش اول شما این است که اطمینان حاصل کنید که هر پیام کامیت به یک فرمت خاص پایبند است. + فقط برای داشتن یک هدف، فرض کنید که هر پیام باید شامل یک رشته باشد که شبیه به "ref: 1234" است زیرا می‌خواهید هر + کامیت به یک مورد کاری در سیستم بلیط شما لینک شود. + شما باید به هر کامیتی که در حال ارسال است نگاه کنید، ببینید آیا آن رشته در پیام کامیت وجود دارد و اگر رشته در + هیچ یک از کامیت‌ها غایب باشد، با خروج غیرصفر از اسکریپت خارج شوید تا ارسال رد شود.

+
+
+

شما می‌توانید لیستی از مقادیر SHA-1 تمام کامیت‌هایی که در حال ارسال هستند را با گرفتن مقادیر + $newrev و $oldrev و ارسال آن‌ها به یک دستور لوله گیت به نام git + rev-list به دست آورید. + این اساساً دستور git log است، اما به‌طور پیش‌فرض فقط مقادیر SHA-1 را چاپ می‌کند و هیچ اطلاعات + دیگری را نشان نمی‌دهد. + بنابراین، برای به دست آوردن لیستی از تمام SHA-1های کامیت معرفی شده بین یک SHA-1 کامیت و دیگری، می‌توانید چیزی + شبیه به این را اجرا کنید:

+
+
+
$ git rev-list 538c33..d14fc7
 d14fc7c847ab946ec39590d87783c69b031bdfb7
 9f585da4401b0a3999e84113824d15245c13f0be
 234071a1be950e2a8d078e6141f5cd20c1e61ad3
 dfa04c9ef3d5197182f13fb5b9b1fb7717d2222a
 17716ec0f1ff5c77eff40b7fe912f9f6cfd0e475
-
-
-
-

You can take that output, loop through each of those commit SHA-1s, grab the message for it, and test that message against a regular expression that looks for a pattern.

-
-
-

You have to figure out how to get the commit message from each of these commits to test. -To get the raw commit data, you can use another plumbing command called git cat-file. -We’ll go over all these plumbing commands in detail in }}">Git Internals; but for now, here’s what that command gives you:

-
-
-
+
+
+
+

شما می‌توانید آن خروجی را بگیرید، از طریق هر یک از آن SHA-1های کامیت حلقه بزنید، پیام آن را بگیرید و آن پیام + را با یک عبارت منظم که به دنبال یک الگو می‌گردد آزمایش کنید.

+
+
+

شما باید بفهمید چگونه می‌توانید پیام کامیت را از هر یک از این کامیت‌ها برای آزمایش به دست آورید. + برای به دست آوردن داده‌های خام کامیت، می‌توانید از یک دستور لوله دیگر به نام git cat-file استفاده + کنید. + ما تمام این دستورات لوله را به تفصیل در + }}">Git Internals + بررسی خواهیم کرد؛ اما در حال حاضر، این چیزی است که آن دستور به شما می‌دهد:

+
+
+
$ git cat-file commit ca82a6
 tree cfda3bf379e4f8dba8717dee55aab78aef7f4daf
 parent 085bb3bcb608e1e8451d4b2432f8ecbe6306e7e7
 author Scott Chacon <schacon@gmail.com> 1205815931 -0700
 committer Scott Chacon <schacon@gmail.com> 1240030591 -0700
 
-Change the version number
-
-
-
-

A simple way to get the commit message from a commit when you have the SHA-1 value is to go to the first blank line and take everything after that. -You can do so with the sed command on Unix systems:

-
-
-
+تغییر شماره نسخه +
+
+
+

یک روش ساده برای به دست آوردن پیام کامیت از یک کامیت زمانی که شما مقدار SHA-1 را دارید این است که به اولین خط + خالی بروید و همه چیز بعد از آن را بگیرید. + شما می‌توانید این کار را با دستور sed در سیستم‌های یونیکس انجام دهید:

+
+
+
$ git cat-file commit ca82a6 | sed '1,/^$/d'
-Change the version number
-
-
-
-

You can use that incantation to grab the commit message from each commit that is trying to be pushed and exit if you see anything that doesn’t match. -To exit the script and reject the push, exit non-zero. -The whole method looks like this:

-
-
-
+تغییر شماره نسخه +
+
+
+

شما می‌توانید از آن جادو برای گرفتن پیام کامیت از هر کامیتی که در حال تلاش برای ارسال است استفاده کنید و اگر + چیزی را ببینید که با آن مطابقت ندارد، خارج شوید. + برای خروج از اسکریپت و رد کردن ارسال، غیرصفر خارج شوید. + کل روش به این صورت است:

+
+
+
$regex = /\[ref: (\d+)\]/
 
-# enforced custom commit message format
+# تحمیل فرمت پیام کامیت سفارشی
 def check_message_format
   missed_revs = `git rev-list #{$oldrev}..#{$newrev}`.split("\n")
   missed_revs.each do |rev|
     message = `git cat-file commit #{rev} | sed '1,/^$/d'`
     if !$regex.match(message)
-      puts "[POLICY] Your message is not formatted correctly"
+      puts "[سیاست] پیام شما به درستی فرمت نشده است"
       exit 1
     end
   end
 end
 check_message_format
-
-
-
-

Putting that in your update script will reject updates that contain commits that have messages that don’t adhere to your rule.

-
-
-
-

Enforcing a User-Based ACL System

-
-

Suppose you want to add a mechanism that uses an access control list (ACL) that specifies which users are allowed to push changes to which parts of your projects. -Some people have full access, and others can only push changes to certain subdirectories or specific files. -To enforce this, you’ll write those rules to a file named acl that lives in your bare Git repository on the server. -You’ll have the update hook look at those rules, see what files are being introduced for all the commits being pushed, and determine whether the user doing the push has access to update all those files.

-
-
-

The first thing you’ll do is write your ACL. -Here you’ll use a format very much like the CVS ACL mechanism: it uses a series of lines, where the first field is avail or unavail, the next field is a comma-delimited list of the users to which the rule applies, and the last field is the path to which the rule applies (blank meaning open access). -All of these fields are delimited by a pipe (|) character.

-
-
-

In this case, you have a couple of administrators, some documentation writers with access to the doc directory, and one developer who only has access to the lib and tests directories, and your ACL file looks like this:

-
-
-
+
+
+
+

قرار دادن آن در اسکریپت update شما به‌روزرسانی‌هایی را که شامل کامیت‌هایی هستند که پیام‌های + آن‌ها به قانون شما پایبند نیستند، رد خواهد کرد.

+
+
+
+

تحمیل یک سیستم ACL مبتنی بر کاربر

+
+

فرض کنید می‌خواهید مکانیزمی اضافه کنید که از یک لیست کنترل دسترسی (ACL) استفاده می‌کند که مشخص می‌کند کدام + کاربران مجاز به ارسال تغییرات به کدام قسمت‌های پروژه‌های شما هستند. + برخی افراد دسترسی کامل دارند و دیگران فقط می‌توانند تغییرات را به زیرپوشه‌های خاص یا فایل‌های خاص ارسال کنند. + برای تحمیل این، شما این قوانین را به فایلی به نام acl می‌نویسید که در مخزن گیت خالی شما در سرور + قرار دارد. + شما هوک update را به این قوانین نگاه می‌کنید، می‌بینید که چه فایل‌هایی برای تمام کامیت‌های ارسال + شده معرفی شده‌اند و تعیین می‌کنید که آیا کاربر در حال ارسال به‌روزرسانی به همه این فایل‌ها دسترسی دارد یا خیر. +

+
+
+

اولین کاری که انجام می‌دهید این است که ACL خود را بنویسید. + در اینجا از فرمت بسیار شبیه به مکانیزم ACL CVS استفاده می‌کنید: این فرمت شامل یک سری خطوط است که در آن اولین + فیلد avail یا unavail است، فیلد بعدی یک لیست جدا شده با کاما از کاربرانی است که + قانون به آن‌ها اعمال می‌شود و آخرین فیلد مسیری است که قانون به آن اعمال می‌شود (خالی به معنای دسترسی باز است). + تمام این فیلدها با یک کاراکتر لوله (|) جدا شده‌اند.

+
+
+

در این مورد، شما چند مدیر، برخی نویسندگان مستندات با دسترسی به دایرکتوری doc و یک توسعه‌دهنده که + فقط به دایرکتوری‌های lib و tests دسترسی دارد، دارید و فایل ACL شما به این صورت است: +

+
+
+
avail|nickh,pjhyett,defunkt,tpw
 avail|usinclair,cdickens,ebronte|doc
 avail|schacon|lib
 avail|schacon|tests
-
-
-
-

You begin by reading this data into a structure that you can use. -In this case, to keep the example simple, you’ll only enforce the avail directives. -Here is a method that gives you an associative array where the key is the user name and the value is an array of paths to which the user has write access:

-
-
-
+
+
+
+

شما با خواندن این داده‌ها به یک ساختار که می‌توانید از آن استفاده کنید، شروع می‌کنید. + در این مورد، برای ساده نگه داشتن مثال، شما فقط دستورات avail را تحمیل خواهید کرد. + در اینجا یک متد است که به شما یک آرایه انجمنی می‌دهد که در آن کلید نام کاربر و مقدار آن آرایه‌ای از مسیرهایی + است که کاربر به آن‌ها دسترسی نوشتن دارد:

+
+
+
def get_acl_access_data(acl_file)
-  # read in ACL data
+  # خواندن داده‌های ACL
   acl_file = File.read(acl_file).split("\n").reject { |line| line == '' }
   access = {}
   acl_file.each do |line|
@@ -191,13 +221,14 @@ 

Enforcing a User-Based ACL System

-
-
-
-

On the ACL file you looked at earlier, this get_acl_access_data method returns a data structure that looks like this:

-
-
-
+
+
+
+

در فایل ACL که قبلاً به آن نگاه کردید، این متد get_acl_access_data یک ساختار داده‌ای را + برمی‌گرداند که به این صورت است:

+
+
+
{"defunkt"=>[nil],
  "tpw"=>[nil],
  "nickh"=>[nil],
@@ -206,32 +237,38 @@ 

Enforcing a User-Based ACL System

-
-
-
-

Now that you have the permissions sorted out, you need to determine what paths the commits being pushed have modified, so you can make sure the user who’s pushing has access to all of them.

-
-
-

You can pretty easily see what files have been modified in a single commit with the --name-only option to the git log command (mentioned briefly in }}">مقدمات گیت):

-
-
-
+
+
+
+

حالا که مجوزها را مرتب کرده‌اید، باید تعیین کنید که کدام مسیرها توسط کامیت‌های ارسال شده تغییر یافته‌اند، + بنابراین می‌توانید مطمئن شوید که کاربری که در حال ارسال است به همه آن‌ها دسترسی دارد.

+
+
+

شما می‌توانید به راحتی ببینید که چه فایل‌هایی در یک کامیت واحد تغییر یافته‌اند با گزینه + --name-only به دستور git log (که به‌طور مختصر در + }}">Git Basics + ذکر شده است):

+
+
+
$ git log -1 --name-only --pretty=format:'' 9f585d
 
 README
 lib/test.rb
-
-
-
-

If you use the ACL structure returned from the get_acl_access_data method and check it against the listed files in each of the commits, you can determine whether the user has access to push all of their commits:

-
-
-
-
# only allows certain users to modify certain subdirectories in a project
+        
+
+
+

اگر از ساختار ACL که از متد get_acl_access_data برگشت داده شده استفاده کنید و آن را با فایل‌های + لیست شده در هر یک از کامیت‌ها بررسی کنید، می‌توانید تعیین کنید که آیا کاربر دسترسی به ارسال همه کامیت‌های خود + را دارد یا خیر:

+
+
+
+
# فقط اجازه می‌دهد کاربران خاصی زیرپوشه‌های خاصی را در یک پروژه تغییر دهند
 def check_directory_perms
   access = get_acl_access_data('acl')
 
-  # see if anyone is trying to push something they can't
+  # ببینید آیا کسی در حال تلاش برای ارسال چیزی است که نمی‌تواند
   new_commits = `git rev-list #{$oldrev}..#{$newrev}`.split("\n")
   new_commits.each do |rev|
     files_modified = `git log -1 --name-only --pretty=format:'' #{rev}`.split("\n")
@@ -239,13 +276,13 @@ 

Enforcing a User-Based ACL SystemEnforcing a User-Based ACL System

-
-
-
-

You get a list of new commits being pushed to your server with git rev-list. -Then, for each of those commits, you find which files are modified and make sure the user who’s pushing has access to all the paths being modified.

-
-
-

Now your users can’t push any commits with badly formed messages or with modified files outside of their designated paths.

-
-
-
-

Testing It Out

-
-

If you run chmod u+x .git/hooks/update, which is the file into which you should have put all this code, and then try to push a commit with a non-compliant message, you get something like this:

-
-
-
+
+
+
+

شما با استفاده از git rev-list لیستی از کامیت‌های جدیدی که به سرور شما ارسال می‌شوند را به دست + می‌آورید. + سپس، برای هر یک از آن کامیت‌ها، فایل‌هایی که تغییر یافته‌اند را پیدا می‌کنید و مطمئن می‌شوید که کاربر که در + حال ارسال است به همه مسیرهای تغییر یافته دسترسی دارد.

+
+
+

حالا کاربران شما نمی‌توانند هیچ کامیتی را با پیام‌های بدفرمت یا با فایل‌های تغییر یافته خارج از مسیرهای تعیین + شده خود ارسال کنند.

+
+
+
+

آزمایش آن

+
+

اگر شما chmod u+x .git/hooks/update را اجرا کنید، که فایلی است که باید تمام این کد را در آن قرار + داده باشید، و سپس سعی کنید یک کامیت با پیام غیرقابل قبول ارسال کنید، چیزی شبیه به این دریافت می‌کنید:

+
+
+
$ git push -f origin master
-Counting objects: 5, done.
-Compressing objects: 100% (3/3), done.
-Writing objects: 100% (3/3), 323 bytes, done.
-Total 3 (delta 1), reused 0 (delta 0)
-Unpacking objects: 100% (3/3), done.
-Enforcing Policies...
+شمارش اشیاء: 5، انجام شد.
+فشرده‌سازی اشیاء: 100% (3/3)، انجام شد.
+نوشتن اشیاء: 100% (3/3)، 323 بایت، انجام شد.
+جمع کل 3 (دلتا 1)، دوباره استفاده شده 0 (دلتا 0)
+باز کردن اشیاء: 100% (3/3)، انجام شد.
+تحمیل سیاست‌ها...
 (refs/heads/master) (8338c5) (c5b616)
-[POLICY] Your message is not formatted correctly
-error: hooks/update exited with error code 1
-error: hook declined to update refs/heads/master
-To git@gitserver:project.git
- ! [remote rejected] master -> master (hook declined)
-error: failed to push some refs to 'git@gitserver:project.git'
-
-
-
-

There are a couple of interesting things here. -First, you see this where the hook starts running.

-
-
-
-
Enforcing Policies...
+[سیاست] پیام شما به درستی فرمت نشده است
+خطا: hooks/update با کد خطای 1 خارج شد
+خطا: هوک به‌روزرسانی را رد کرد
+به git@gitserver:project.git
+ ! [رد شده از راه دور] master -> master (هوک رد شد)
+خطا: ارسال برخی از مراجع به 'git@gitserver:project.git' ناموفق بود
+
+
+
+

چند چیز جالب در اینجا وجود دارد. + اولاً، شما اینجا را می‌بینید که هوک شروع به اجرا می‌کند.

+
+
+
+
تحمیل سیاست‌ها...
 (refs/heads/master) (fb8c72) (c56860)
-
-
-
-

Remember that you printed that out at the very beginning of your update script. -Anything your script echoes to stdout will be transferred to the client.

-
-
-

The next thing you’ll notice is the error message.

-
-
-
-
[POLICY] Your message is not formatted correctly
-error: hooks/update exited with error code 1
-error: hook declined to update refs/heads/master
-
-
-
-

The first line was printed out by you, the other two were Git telling you that the update script exited non-zero and that is what is declining your push. -Lastly, you have this:

-
-
-
-
To git@gitserver:project.git
- ! [remote rejected] master -> master (hook declined)
-error: failed to push some refs to 'git@gitserver:project.git'
-
-
-
-

You’ll see a remote rejected message for each reference that your hook declined, and it tells you that it was declined specifically because of a hook failure.

-
-
-

Furthermore, if someone tries to edit a file they don’t have access to and push a commit containing it, they will see something similar. -For instance, if a documentation author tries to push a commit modifying something in the lib directory, they see

-
-
-
-
[POLICY] You do not have access to push to lib/test.rb
-
-
-
-

From now on, as long as that update script is there and executable, your repository will never have a commit message without your pattern in it, and your users will be sandboxed.

-
-
-
-
-

Client-Side Hooks

-
-

The downside to this approach is the whining that will inevitably result when your users' commit pushes are rejected. -Having their carefully crafted work rejected at the last minute can be extremely frustrating and confusing; and furthermore, they will have to edit their history to correct it, which isn’t always for the faint of heart.

-
-
-

The answer to this dilemma is to provide some client-side hooks that users can run to notify them when they’re doing something that the server is likely to reject. -That way, they can correct any problems before committing and before those issues become more difficult to fix. -Because hooks aren’t transferred with a clone of a project, you must distribute these scripts some other way and then have your users copy them to their .git/hooks directory and make them executable. -You can distribute these hooks within the project or in a separate project, but Git won’t set them up automatically.

-
-
-

To begin, you should check your commit message just before each commit is recorded, so you know the server won’t reject your changes due to badly formatted commit messages. -To do this, you can add the commit-msg hook. -If you have it read the message from the file passed as the first argument and compare that to the pattern, you can force Git to abort the commit if there is no match:

-
-
-
+
+
+
+

به یاد داشته باشید که شما این را در ابتدای اسکریپت به‌روزرسانی خود چاپ کردید. + هر چیزی که اسکریپت شما به stdout چاپ کند به کلاینت منتقل خواهد شد.

+
+
+

چیز بعدی که متوجه خواهید شد پیام خطا است.

+
+
+
+
[سیاست] پیام شما به درستی فرمت نشده است
+خطا: hooks/update با کد خطای 1 خارج شد
+خطا: هوک به‌روزرسانی را رد کرد
+
+
+
+

خط اول توسط شما چاپ شده است، دو خط دیگر گیت به شما می‌گوید که اسکریپت به‌روزرسانی غیرصفر خارج شده و این همان + چیزی است که ارسال شما را رد می‌کند. + در نهایت، شما این را دارید:

+
+
+
+
به git@gitserver:project.git
+ ! [رد شده از راه دور] master -> master (هوک رد شد)
+خطا: ارسال برخی از مراجع به 'git@gitserver:project.git' ناموفق بود
+
+
+
+

شما یک پیام رد شده از راه دور برای هر مرجعی که هوک شما رد کرده است خواهید دید و به شما می‌گوید که به‌طور خاص + به دلیل یک خطای هوک رد شده است.

+
+
+

علاوه بر این، اگر کسی سعی کند فایلی را که به آن دسترسی ندارد و کامیتی حاوی آن را ارسال کند ویرایش کند، چیزی + مشابه خواهد دید. + برای مثال، اگر یک نویسنده مستندات سعی کند یک کامیت را که چیزی در دایرکتوری lib را تغییر می‌دهد + ارسال کند، او این را می‌بیند:

+
+
+
+
[سیاست] شما به ارسال به lib/test.rb دسترسی ندارید
+
+
+
+

از این پس، به شرطی که آن اسکریپت update وجود داشته باشد و قابل اجرا باشد، مخزن شما هرگز پیام + کامیتی بدون الگوی شما نخواهد داشت و کاربران شما در یک محیط محدود خواهند بود.

+
+
+
+
+

هوک‌های سمت کلاینت

+
+

معایب این رویکرد این است که ناله‌ای که به طور حتم زمانی که ارسال‌های کامیت کاربران شما رد می‌شود، به وجود + می‌آید. + رد کردن کارهای به دقت طراحی شده آن‌ها در آخرین لحظه می‌تواند بسیار ناامیدکننده و گیج‌کننده باشد؛ و علاوه بر این، + آن‌ها باید تاریخچه خود را ویرایش کنند تا آن را اصلاح کنند، که همیشه برای افراد ضعیف نیست.

+
+
+

پاسخ به این معضل این است که برخی هوک‌های سمت کلاینت را ارائه دهید که کاربران می‌توانند برای اطلاع از زمانی که + در حال انجام کاری هستند که احتمالاً سرور آن را رد خواهد کرد، اجرا کنند. + به این ترتیب، آن‌ها می‌توانند هر گونه مشکلی را قبل از کامیت کردن و قبل از اینکه آن مسائل دشوارتر شود، اصلاح + کنند. + زیرا هوک‌ها با یک کپی از یک پروژه منتقل نمی‌شوند، شما باید این اسکریپت‌ها را به روشی دیگر توزیع کنید و سپس از + کاربران خود بخواهید که آن‌ها را به دایرکتوری .git/hooks خود کپی کنند و آن‌ها را قابل اجرا کنند. + شما می‌توانید این هوک‌ها را درون پروژه یا در یک پروژه جداگانه توزیع کنید، اما گیت به‌طور خودکار آن‌ها را تنظیم + نخواهد کرد.

+
+
+

برای شروع، شما باید پیام کامیت خود را درست قبل از اینکه هر کامیت ثبت شود بررسی کنید، بنابراین می‌دانید که سرور + تغییرات شما را به دلیل پیام‌های کامیت بدفرمت رد نخواهد کرد. + برای این کار، می‌توانید هوک commit-msg را اضافه کنید. + اگر آن را از فایلی که به عنوان اولین آرگومان ارسال شده است بخوانید و آن را با الگو مقایسه کنید، می‌توانید گیت را + مجبور کنید که اگر هیچ تطابقی وجود نداشته باشد، کامیت را متوقف کند:

+
+
+
#!/usr/bin/env ruby
 message_file = ARGV[0]
 message = File.read(message_file)
@@ -364,44 +418,46 @@ 

Client-Side Hooks

$regex = /\[ref: (\d+)\]/ if !$regex.match(message) - puts "[POLICY] Your message is not formatted correctly" + puts "[سیاست] پیام شما به درستی فرمت نشده است" exit 1 end
-
-
-
-

If that script is in place (in .git/hooks/commit-msg) and executable, and you commit with a message that isn’t properly formatted, you see this:

-
-
-
+
+
+
+

اگر آن اسکریپت در محل (در .git/hooks/commit-msg) و قابل اجرا باشد و شما با پیامی که به درستی فرمت + نشده است کامیت کنید، این را می‌بینید:

+
+
+
$ git commit -am 'Test'
-[POLICY] Your message is not formatted correctly
-
-
-
-

No commit was completed in that instance. -However, if your message contains the proper pattern, Git allows you to commit:

-
-
-
+[سیاست] پیام شما به درستی فرمت نشده است +
+
+
+

در آن حالت هیچ کامیتی انجام نشد. + با این حال، اگر پیام شما شامل الگوی مناسب باشد، گیت به شما اجازه می‌دهد که کامیت کنید:

+
+
+
$ git commit -am 'Test [ref: 132]'
 [master e05c914] Test [ref: 132]
- 1 file changed, 1 insertions(+), 0 deletions(-)
-
-
-
-

Next, you want to make sure you aren’t modifying files that are outside your ACL scope. -If your project’s .git directory contains a copy of the ACL file you used previously, then the following pre-commit script will enforce those constraints for you:

-
-
-
+ 1 فایل تغییر یافته، 1 درج (+)، 0 حذف (-) +
+
+
+

بعد، شما می‌خواهید مطمئن شوید که فایل‌هایی را که خارج از دامنه ACL خود تغییر نمی‌دهید. + اگر دایرکتوری .git پروژه شما شامل یک کپی از فایل ACL است که قبلاً استفاده کرده‌اید، سپس اسکریپت + pre-commit زیر این محدودیت‌ها را برای شما تحمیل خواهد کرد:

+
+
+
#!/usr/bin/env ruby
 
 $user    = ENV['USER']
 
-# [ insert acl_access_data method from above ]
+# [ وارد کردن متد acl_access_data از بالا ]
 
-# only allows certain users to modify certain subdirectories in a project
+# فقط اجازه می‌دهد کاربران خاصی زیرپوشه‌های خاصی را در یک پروژه تغییر دهند
 def check_directory_perms
   access = get_acl_access_data('.git/acl')
 
@@ -414,70 +470,79 @@ 

Client-Side Hooks

has_file_access = true end if !has_file_access - puts "[POLICY] You do not have access to push to #{path}" + puts "[سیاست] شما به ارسال به #{path} دسترسی ندارید" exit 1 end end end check_directory_perms
-
-
-
-

This is roughly the same script as the server-side part, but with two important differences. -First, the ACL file is in a different place, because this script runs from your working directory, not from your .git directory. -You have to change the path to the ACL file from this

-
-
-
-
access = get_acl_access_data('acl')
-
-
-
-

to this:

-
-
-
-
access = get_acl_access_data('.git/acl')
-
-
-
-

The other important difference is the way you get a listing of the files that have been changed. -Because the server-side method looks at the log of commits, and, at this point, the commit hasn’t been recorded yet, you must get your file listing from the staging area instead. -Instead of

-
-
-
-
files_modified = `git log -1 --name-only --pretty=format:'' #{ref}`
-
-
-
-

you have to use

-
-
-
-
files_modified = `git diff-index --cached --name-only HEAD`
-
-
-
-

But those are the only two differences – otherwise, the script works the same way. -One caveat is that it expects you to be running locally as the same user you push as to the remote machine. -If that is different, you must set the $user variable manually.

-
-
-

One other thing we can do here is make sure the user doesn’t push non-fast-forwarded references. -To get a reference that isn’t a fast-forward, you either have to rebase past a commit you’ve already pushed up or try pushing a different local branch up to the same remote branch.

-
-
-

Presumably, the server is already configured with receive.denyDeletes and receive.denyNonFastForwards to enforce this policy, so the only accidental thing you can try to catch is rebasing commits that have already been pushed.

-
-
-

Here is an example pre-rebase script that checks for that. -It gets a list of all the commits you’re about to rewrite and checks whether they exist in any of your remote references. -If it sees one that is reachable from one of your remote references, it aborts the rebase.

-
-
-
+
+
+
+

این تقریباً همان اسکریپت است که در سمت سرور وجود دارد، اما با دو تفاوت مهم. + اولاً، فایل ACL در مکان متفاوتی است، زیرا این اسکریپت از دایرکتوری کاری شما اجرا می‌شود، نه از دایرکتوری .git + شما. + شما باید مسیر فایل ACL را از این

+
+
+
+
access = get_acl_access_data('acl')
+
+
+
+

به این تغییر دهید:

+
+
+
+
access = get_acl_access_data('.git/acl')
+
+
+
+

تفاوت مهم دیگر این است که چگونه لیستی از فایل‌هایی که تغییر کرده‌اند را به دست می‌آورید. + زیرا روش سمت سرور به تاریخچه کامیت‌ها نگاه می‌کند و در این مرحله، کامیت هنوز ثبت نشده است، شما باید لیست + فایل‌های خود را از ناحیه staging به دست آورید. + به جای

+
+
+
+
files_modified = `git log -1 --name-only --pretty=format:'' #{ref}`
+
+
+
+

شما باید از این استفاده کنید:

+
+
+
+
files_modified = `git diff-index --cached --name-only HEAD`
+
+
+
+

اما این تنها دو تفاوت است – در غیر این صورت، اسکریپت به همان شیوه کار می‌کند. + یک نکته این است که انتظار دارد شما به‌طور محلی به عنوان همان کاربری که به عنوان کاربر از راه دور ارسال می‌کنید، + اجرا کنید. + اگر این متفاوت باشد، باید متغیر $user را به‌طور دستی تنظیم کنید.

+
+
+

یک چیز دیگر که می‌توانیم در اینجا انجام دهیم این است که مطمئن شویم کاربر مراجع غیر پیشرفته را ارسال نمی‌کند. + برای به دست آوردن مرجعی که پیشرفته نیست، شما یا باید از یک کامیت که قبلاً ارسال کرده‌اید، بازسازی کنید یا سعی + کنید یک شاخه محلی متفاوت را به همان شاخه از راه دور ارسال کنید.

+
+
+

به احتمال زیاد، سرور قبلاً با receive.denyDeletes و receive.denyNonFastForwards برای + تحمیل این سیاست پیکربندی شده است، بنابراین تنها چیزی که می‌توانید سعی کنید تصادفی بگیرید، بازسازی کامیت‌هایی است + که قبلاً ارسال شده‌اند.

+
+
+

در اینجا یک اسکریپت pre-rebase نمونه وجود دارد که برای این کار بررسی می‌کند. + این لیستی از تمام کامیت‌هایی که در حال بازنویسی هستید را به دست می‌آورد و بررسی می‌کند که آیا آن‌ها در هر یک از + مراجع راه دور شما وجود دارند یا خیر. + اگر ببیند که یکی از آن‌ها از یکی از مراجع راه دور قابل دسترسی است، بازسازی را متوقف می‌کند.

+
+
+
#!/usr/bin/env ruby
 
 base_branch = ARGV[0]
@@ -494,29 +559,36 @@ 

Client-Side Hooks

remote_refs.each do |remote_ref| shas_pushed = `git rev-list ^#{sha}^@ refs/remotes/#{remote_ref}` if shas_pushed.split("\n").include?(sha) - puts "[POLICY] Commit #{sha} has already been pushed to #{remote_ref}" + puts "[سیاست] کامیت #{sha} قبلاً به #{remote_ref} ارسال شده است" exit 1 end end end
-
-
-
-

This script uses a syntax that wasn’t covered in }}">Revision Selection. -You get a list of commits that have already been pushed up by running this:

-
-
-
-
`git rev-list ^#{sha}^@ refs/remotes/#{remote_ref}`
-
-
-
-

The SHA^@ syntax resolves to all the parents of that commit. -You’re looking for any commit that is reachable from the last commit on the remote and that isn’t reachable from any parent of any of the SHA-1s you’re trying to push up – meaning it’s a fast-forward.

-
-
-

The main drawback to this approach is that it can be very slow and is often unnecessary – if you don’t try to force the push with -f, the server will warn you and not accept the push. -However, it’s an interesting exercise and can in theory help you avoid a rebase that you might later have to go back and fix.

-
-
- \ No newline at end of file +
+
+
+

این اسکریپت از یک سینتکس استفاده می‌کند که در + }}">Revision Selection + پوشش داده نشده است. + شما با اجرای این:

+
+
+
+
`git rev-list ^#{sha}^@ refs/remotes/#{remote_ref}`
+
+
+
+

لیستی از کامیت‌هایی که قبلاً ارسال شده‌اند به دست می‌آورید. + سینتکس SHA^@ به تمام والدین آن کامیت اشاره می‌کند. + شما به دنبال هر کامیتی هستید که از آخرین کامیت در راه دور قابل دسترسی باشد و از هیچ والدینی از هر یک از + SHA-1هایی که در حال تلاش برای ارسال هستید، قابل دسترسی نباشد – به این معنی که پیشرفته است.

+
+
+

معایب اصلی این رویکرد این است که می‌تواند بسیار کند باشد و اغلب غیرضروری است – اگر شما سعی نکنید با + -f ارسال اجباری کنید، سرور به شما هشدار می‌دهد و ارسال را قبول نمی‌کند. + با این حال، این یک تمرین جالب است و می‌تواند به‌طور نظری به شما کمک کند تا از یک بازسازی که ممکن است بعداً مجبور + به اصلاح آن شوید، جلوگیری کنید.

+
+
+ +
\ No newline at end of file diff --git a/external/book/content/book/fa/v2/Customizing-Git-Git-Attributes.html b/external/book/content/book/fa/v2/Customizing-Git-Git-Attributes.html index 6dd1f17e14..64a3173f21 100644 --- a/external/book/content/book/fa/v2/Customizing-Git-Git-Attributes.html +++ b/external/book/content/book/fa/v2/Customizing-Git-Git-Attributes.html @@ -17,156 +17,188 @@ next: book/fa/v2/Customizing-Git-Git-Hooks title: Git - Git Attributes --- -

Git Attributes

-
-

-Some of these settings can also be specified for a path, so that Git applies those settings only for a subdirectory or subset of files. -These path-specific settings are called Git attributes and are set either in a .gitattributes file in one of your directories (normally the root of your project) or in the .git/info/attributes file if you don’t want the attributes file committed with your project.

-
-
-

Using attributes, you can do things like specify separate merge strategies for individual files or directories in your project, tell Git how to diff non-text files, or have Git filter content before you check it into or out of Git. -In this section, you’ll learn about some of the attributes you can set on your paths in your Git project and see a few examples of using this feature in practice.

-
-
-

Binary Files

-
-

-One cool trick for which you can use Git attributes is telling Git which files are binary (in cases it otherwise may not be able to figure out) and giving Git special instructions about how to handle those files. -For instance, some text files may be machine generated and not diffable, whereas some binary files can be diffed. -You’ll see how to tell Git which is which.

-
-
-

Identifying Binary Files

-
-

Some files look like text files but for all intents and purposes are to be treated as binary data. -For instance, Xcode projects on macOS contain a file that ends in .pbxproj, which is basically a JSON (plain-text JavaScript data format) dataset written out to disk by the IDE, which records your build settings and so on. -Although it’s technically a text file (because it’s all UTF-8), you don’t want to treat it as such because it’s really a lightweight database – you can’t merge the contents if two people change it, and diffs generally aren’t helpful. -The file is meant to be consumed by a machine. -In essence, you want to treat it like a binary file.

-
-
-

To tell Git to treat all pbxproj files as binary data, add the following line to your .gitattributes file:

-
-
-
-
*.pbxproj binary
-
-
-
-

Now, Git won’t try to convert or fix CRLF issues; nor will it try to compute or print a diff for changes in this file when you run git show or git diff on your project.

-
-
-
-

Diffing Binary Files

-
-

You can also use the Git attributes functionality to effectively diff binary files. -You do this by telling Git how to convert your binary data to a text format that can be compared via the normal diff.

-
-
-

First, you’ll use this technique to solve one of the most annoying problems known to humanity: version-controlling Microsoft Word documents. -Everyone knows that Word is the most horrific editor around, but oddly, everyone still uses it. -If you want to version-control Word documents, you can stick them in a Git repository and commit every once in a while; but what good does that do? -If you run git diff normally, you only see something like this:

-
-
-
+
+

ویژگی‌های گیت

+
+

+ برخی از این تنظیمات همچنین می‌توانند برای یک مسیر مشخص شوند، به طوری که گیت این تنظیمات را فقط برای یک زیرپوشه یا + زیرمجموعه‌ای از فایل‌ها اعمال کند. + این تنظیمات خاص مسیر به نام ویژگی‌های گیت شناخته می‌شوند و در یک فایل .gitattributes در یکی از + دایرکتوری‌های شما (معمولاً ریشه پروژه شما) یا در فایل .git/info/attributes تنظیم می‌شوند اگر + نمی‌خواهید فایل ویژگی‌ها با پروژه شما کامیت شود.

+
+
+

با استفاده از ویژگی‌ها، می‌توانید کارهایی مانند مشخص کردن استراتژی‌های ادغام جداگانه برای فایل‌ها یا + دایرکتوری‌های خاص در پروژه خود، به گیت بگویید که چگونه فایل‌های غیرمتنی را مقایسه کند، یا از گیت بخواهید که محتوا + را قبل از اینکه آن را به گیت اضافه کنید یا از آن خارج کنید، فیلتر کند. + در این بخش، شما با برخی از ویژگی‌هایی که می‌توانید بر روی مسیرهای خود در پروژه گیت خود تنظیم کنید آشنا خواهید شد و + چند مثال از استفاده از این ویژگی در عمل را خواهید دید.

+
+
+

فایل‌های باینری

+
+

+ یکی از ترفندهای جالبی که می‌توانید با استفاده از ویژگی‌های گیت انجام دهید، این است که به گیت بگویید کدام فایل‌ها + باینری هستند (در مواردی که ممکن است نتواند تشخیص دهد) و به گیت دستورالعمل‌های خاصی درباره نحوه مدیریت آن فایل‌ها + بدهید. + به عنوان مثال، برخی از فایل‌های متنی ممکن است به صورت ماشینی تولید شده و قابل مقایسه نباشند، در حالی که برخی از + فایل‌های باینری می‌توانند مقایسه شوند. + شما خواهید دید که چگونه به گیت بگویید کدام یک کدام است.

+
+
+

شناسایی فایل‌های باینری

+
+

برخی از فایل‌ها به نظر می‌رسند که فایل‌های متنی هستند اما به هر دلیلی باید به عنوان داده‌های باینری در نظر + گرفته شوند. + به عنوان مثال، پروژه‌های Xcode در macOS شامل فایلی هستند که با .pbxproj پایان می‌یابد، که اساساً + یک مجموعه داده JSON (فرمت داده‌های جاوا اسکریپت متنی) است که توسط IDE به دیسک نوشته شده و تنظیمات ساخت شما و + غیره را ثبت می‌کند. + اگرچه این فایل به طور فنی یک فایل متنی است (زیرا همه چیز UTF-8 است)، اما نمی‌خواهید آن را به عنوان چنین در نظر + بگیرید زیرا در واقع یک پایگاه داده سبک است – شما نمی‌توانید محتویات آن را ادغام کنید اگر دو نفر آن را تغییر + کنند و مقایسه‌ها معمولاً مفید نیستند. + این فایل به منظور مصرف توسط یک ماشین طراحی شده است. + در واقع، شما می‌خواهید آن را مانند یک فایل باینری در نظر بگیرید.

+
+
+

برای اینکه به گیت بگویید که تمام فایل‌های pbxproj را به عنوان داده‌های باینری در نظر بگیرد، خط + زیر را به فایل .gitattributes خود اضافه کنید:

+
+
+
+
*.pbxproj binary
+
+
+
+

اکنون، گیت سعی نخواهد کرد که مشکلات CRLF را تبدیل یا اصلاح کند؛ همچنین سعی نخواهد کرد که تفاوت‌ها را برای + تغییرات در این فایل محاسبه یا چاپ کند زمانی که شما git show یا git diff را در پروژه + خود اجرا می‌کنید.

+
+
+
+

مقایسه فایل‌های باینری

+
+

شما همچنین می‌توانید از قابلیت ویژگی‌های گیت برای مقایسه مؤثر فایل‌های باینری استفاده کنید. + شما این کار را با گفتن به گیت انجام می‌دهید که چگونه داده‌های باینری خود را به یک فرمت متنی تبدیل کند که بتوان + آن را از طریق مقایسه عادی مقایسه کرد.

+
+
+

اول، شما از این تکنیک برای حل یکی از آزاردهنده‌ترین مشکلات شناخته شده برای بشریت استفاده خواهید کرد: کنترل + نسخه اسناد Microsoft Word. + همه می‌دانند که Word بدترین ویرایشگر است، اما به طرز عجیبی، همه هنوز از آن استفاده می‌کنند. + اگر می‌خواهید اسناد Word را کنترل نسخه کنید، می‌توانید آن‌ها را در یک مخزن گیت قرار دهید و هر از گاهی کامیت + کنید؛ اما این چه فایده‌ای دارد؟ + اگر شما به طور معمول git diff را اجرا کنید، فقط چیزی شبیه به این را خواهید دید:

+
+
+
$ git diff
 diff --git a/chapter1.docx b/chapter1.docx
 index 88839c4..4afcb7c 100644
 Binary files a/chapter1.docx and b/chapter1.docx differ
-
-
-
-

You can’t directly compare two versions unless you check them out and scan them manually, right? -It turns out you can do this fairly well using Git attributes. -Put the following line in your .gitattributes file:

-
-
-
-
*.docx diff=word
-
-
-
-

This tells Git that any file that matches this pattern (.docx) should use the “word” filter when you try to view a diff that contains changes. -What is the “word” filter? -You have to set it up. -Here you’ll configure Git to use the docx2txt program to convert Word documents into readable text files, which it will then diff properly.

-
-
-

First, you’ll need to install docx2txt; you can download it from https://sourceforge.net/projects/docx2txt. -Follow the instructions in the INSTALL file to put it somewhere your shell can find it. -Next, you’ll write a wrapper script to convert output to the format Git expects. -Create a file that’s somewhere in your path called docx2txt, and add these contents:

-
-
-
+
+
+
+

شما نمی‌توانید دو نسخه را به طور مستقیم مقایسه کنید مگر اینکه آن‌ها را بررسی کنید و به صورت دستی اسکن کنید، + درست است؟ + به نظر می‌رسد که می‌توانید این کار را به خوبی با استفاده از ویژگی‌های گیت انجام دهید. + خط زیر را در فایل .gitattributes خود قرار دهید:

+
+
+
+
*.docx diff=word
+
+
+
+

این به گیت می‌گوید که هر فایلی که با این الگو مطابقت دارد (.docx) باید از فیلتر "word" استفاده + کند زمانی که شما سعی می‌کنید تفاوت‌هایی را مشاهده کنید که شامل تغییرات است. + فیلتر "word" چیست؟ + شما باید آن را تنظیم کنید. + در اینجا شما گیت را پیکربندی می‌کنید تا از برنامه docx2txt برای تبدیل اسناد Word به فایل‌های متنی + قابل خواندن استفاده کند، که سپس به درستی مقایسه می‌شوند.

+
+
+

اول، شما باید docx2txt را نصب کنید؛ می‌توانید آن را از https://sourceforge.net/projects/docx2txt + دانلود کنید. + دستورالعمل‌های موجود در فایل INSTALL را دنبال کنید تا آن را در جایی قرار دهید که شل شما بتواند آن + را پیدا کند. + سپس، شما یک اسکریپت wrapper برای تبدیل خروجی به فرمت مورد انتظار گیت خواهید نوشت. + فایلی که در مسیر شما قرار دارد به نام docx2txt ایجاد کنید و این محتویات را اضافه کنید:

+
+
+
#!/bin/bash
 docx2txt.pl "$1" -
-
-
-
-

Don’t forget to chmod a+x that file. -Finally, you can configure Git to use this script:

-
-
-
-
$ git config diff.word.textconv docx2txt
-
-
-
-

Now Git knows that if it tries to do a diff between two snapshots, and any of the files end in .docx, it should run those files through the “word” filter, which is defined as the docx2txt program. -This effectively makes nice text-based versions of your Word files before attempting to diff them.

-
-
-

Here’s an example: Chapter 1 of this book was converted to Word format and committed in a Git repository. -Then a new paragraph was added. -Here’s what git diff shows:

-
-
-
+
+
+
+

فراموش نکنید که به آن فایل chmod a+x بدهید. + در نهایت، می‌توانید گیت را پیکربندی کنید تا از این اسکریپت استفاده کند:

+
+
+
+
$ git config diff.word.textconv docx2txt
+
+
+
+

اکنون گیت می‌داند که اگر سعی کند تفاوتی بین دو snapshot انجام دهد و هر یک از فایل‌ها با .docx + پایان یابد، باید آن فایل‌ها را از طریق فیلتر "word" که به عنوان برنامه docx2txt تعریف شده است، + اجرا کند. + این به طور مؤثری نسخه‌های متنی خوبی از فایل‌های Word شما را قبل از تلاش برای مقایسه آن‌ها ایجاد می‌کند.

+
+
+

در اینجا یک مثال است: فصل 1 این کتاب به فرمت Word تبدیل شده و در یک مخزن گیت کامیت شده است. + سپس یک پاراگراف جدید اضافه شده است. + این است که git diff نشان می‌دهد:

+
+
+
$ git diff
 diff --git a/chapter1.docx b/chapter1.docx
 index 0b013ca..ba25db5 100644
 --- a/chapter1.docx
 +++ b/chapter1.docx
 @@ -2,6 +2,7 @@
- This chapter will be about getting started with Git. We will begin at the beginning by explaining some background on version control tools, then move on to how to get Git running on your system and finally how to get it setup to start working with. At the end of this chapter you should understand why Git is around, why you should use it and you should be all setup to do so.
- 1.1. About Version Control
- What is "version control", and why should you care? Version control is a system that records changes to a file or set of files over time so that you can recall specific versions later. For the examples in this book you will use software source code as the files being version controlled, though in reality you can do this with nearly any type of file on a computer.
-+Testing: 1, 2, 3.
- If you are a graphic or web designer and want to keep every version of an image or layout (which you would most certainly want to), a Version Control System (VCS) is a very wise thing to use. It allows you to revert files back to a previous state, revert the entire project back to a previous state, compare changes over time, see who last modified something that might be causing a problem, who introduced an issue and when, and more. Using a VCS also generally means that if you screw things up or lose files, you can easily recover. In addition, you get all this for very little overhead.
- 1.1.1. Local Version Control Systems
- Many people's version-control method of choice is to copy files into another directory (perhaps a time-stamped directory, if they're clever). This approach is very common because it is so simple, but it is also incredibly error prone. It is easy to forget which directory you're in and accidentally write to the wrong file or copy over files you don't mean to.
-
-
-
-

Git successfully and succinctly tells us that we added the string “Testing: 1, 2, 3.”, which is correct. -It’s not perfect – formatting changes wouldn’t show up here – but it certainly works.

-
-
-

Another interesting problem you can solve this way involves diffing image files. -One way to do this is to run image files through a filter that extracts their EXIF information – metadata that is recorded with most image formats. -If you download and install the exiftool program, you can use it to convert your images into text about the metadata, so at least the diff will show you a textual representation of any changes that happened. -Put the following line in your .gitattributes file:

-
-
-
-
*.png diff=exif
-
-
-
-

Configure Git to use this tool:

-
-
-
-
$ git config diff.exif.textconv exiftool
-
-
-
-

If you replace an image in your project and run git diff, you see something like this:

-
-
-
+ این فصل درباره شروع به کار با گیت خواهد بود. ما با توضیح برخی از زمینه‌ها در مورد ابزارهای کنترل نسخه شروع خواهیم کرد، سپس به نحوه راه‌اندازی گیت در سیستم شما و در نهایت نحوه تنظیم آن برای شروع کار خواهیم پرداخت. در پایان این فصل شما باید درک کنید که چرا گیت وجود دارد، چرا باید از آن استفاده کنید و باید به طور کامل آماده باشید تا این کار را انجام دهید. + 1.1. درباره کنترل نسخه + کنترل نسخه چیست و چرا باید به آن اهمیت دهید؟ کنترل نسخه سیستمی است که تغییرات را در یک فایل یا مجموعه‌ای از فایل‌ها در طول زمان ثبت می‌کند تا بتوانید نسخه‌های خاصی را بعداً به یاد بیاورید. برای مثال‌ها در این کتاب، شما از کد منبع نرم‌افزار به عنوان فایل‌های تحت کنترل نسخه استفاده خواهید کرد، اگرچه در واقع می‌توانید این کار را با تقریباً هر نوع فایلی در یک کامپیوتر انجام دهید. ++آزمایش: 1، 2، 3. + اگر شما یک طراح گرافیک یا وب هستید و می‌خواهید هر نسخه از یک تصویر یا طرح را نگه دارید (که قطعاً می‌خواهید)، استفاده از یک سیستم کنترل نسخه (VCS) بسیار عاقلانه است. این به شما اجازه می‌دهد تا فایل‌ها را به حالت قبلی برگردانید، کل پروژه را به حالت قبلی برگردانید، تغییرات را در طول زمان مقایسه کنید، ببینید چه کسی آخرین بار چیزی را تغییر داده که ممکن است باعث ایجاد مشکل شود، چه کسی یک مشکل را معرفی کرده و چه زمانی، و بیشتر. استفاده از یک VCS همچنین به طور کلی به این معنی است که اگر چیزها را خراب کنید یا فایل‌ها را گم کنید، می‌توانید به راحتی آن‌ها را بازیابی کنید. علاوه بر این، شما تمام این‌ها را با هزینه بسیار کمی دریافت می‌کنید. + 1.1.1. سیستم‌های کنترل نسخه محلی + روش کنترل نسخه انتخابی بسیاری از مردم این است که فایل‌ها را به یک دایرکتوری دیگر کپی کنند (شاید یک دایرکتوری با زمان‌مهر، اگر آن‌ها باهوش باشند). این رویکرد بسیار رایج است زیرا بسیار ساده است، اما همچنین به شدت مستعد خطاست. به راحتی می‌توان فراموش کرد که در کدام دایرکتوری هستید و به طور تصادفی به فایل اشتباهی بنویسید یا فایل‌هایی را که نمی‌خواهید کپی کنید. +
+
+
+

گیت به طور موفقیت‌آمیز و مختصر به ما می‌گوید که رشته "آزمایش: 1، 2، 3." را اضافه کرده‌ایم، که درست است. + این کامل نیست – تغییرات فرمت در اینجا نشان داده نمی‌شوند – اما قطعاً کار می‌کند.

+
+
+

یک مشکل جالب دیگر که می‌توانید اینگونه حل کنید، مقایسه فایل‌های تصویری است. + یک راه برای انجام این کار این است که فایل‌های تصویری را از طریق یک فیلتر که اطلاعات EXIF آن‌ها را استخراج + می‌کند، اجرا کنید – متاداده‌ای که با اکثر فرمت‌های تصویری ثبت می‌شود. + اگر شما برنامه exiftool را دانلود و نصب کنید، می‌توانید از آن برای تبدیل تصاویر خود به متن درباره + متاداده استفاده کنید، بنابراین حداقل تفاوت‌ها نمایشی متنی از هر تغییری که اتفاق افتاده است را نشان می‌دهد. + خط زیر را در فایل .gitattributes خود قرار دهید:

+
+
+
+
*.png diff=exif
+
+
+
+

گیت را پیکربندی کنید تا از این ابزار استفاده کند:

+
+
+
+
$ git config diff.exif.textconv exiftool
+
+
+
+

اگر شما یک تصویر را در پروژه خود جایگزین کنید و git diff را اجرا کنید، چیزی شبیه به این را + خواهید دید:

+
+
+
diff --git a/image.png b/image.png
 index 88839c4..4afcb7c 100644
 --- a/image.png
@@ -185,272 +217,310 @@ 

Diffing Binary Files

+Image Height : 827 Bit Depth : 8 Color Type : RGB with Alpha
-
-
-
-

You can easily see that the file size and image dimensions have both changed.

-
-
-
-
-

Keyword Expansion

-
-

-SVN- or CVS-style keyword expansion is often requested by developers used to those systems. -The main problem with this in Git is that you can’t modify a file with information about the commit after you’ve committed, because Git checksums the file first. -However, you can inject text into a file when it’s checked out and remove it again before it’s added to a commit. -Git attributes offers you two ways to do this.

-
-
-

First, you can inject the SHA-1 checksum of a blob into an $Id$ field in the file automatically. -If you set this attribute on a file or set of files, then the next time you check out that branch, Git will replace that field with the SHA-1 of the blob. -It’s important to notice that it isn’t the SHA-1 of the commit, but of the blob itself. -Put the following line in your .gitattributes file:

-
-
-
-
*.txt ident
-
-
-
-

Add an $Id$ reference to a test file:

-
-
-
-
$ echo '$Id$' > test.txt
-
-
-
-

The next time you check out this file, Git injects the SHA-1 of the blob:

-
-
-
+
+
+
+

شما به راحتی می‌توانید ببینید که اندازه فایل و ابعاد تصویر هر دو تغییر کرده‌اند.

+
+
+
+
+

گسترش کلیدواژه

+
+

+ گسترش کلیدواژه به سبک SVN یا CVS اغلب توسط توسعه‌دهندگانی که به آن سیستم‌ها عادت دارند درخواست می‌شود. + مشکل اصلی با این در گیت این است که شما نمی‌توانید فایلی را با اطلاعات مربوط به کامیت پس از اینکه کامیت کرده‌اید، + تغییر دهید، زیرا گیت ابتدا checksum فایل را بررسی می‌کند. + با این حال، شما می‌توانید متن را هنگام چک‌اوت به یک فایل تزریق کنید و قبل از اینکه دوباره به یک کامیت اضافه شود، + آن را حذف کنید. + ویژگی‌های گیت به شما دو روش برای انجام این کار ارائه می‌دهد.

+
+
+

اول، شما می‌توانید checksum SHA-1 یک blob را به یک فیلد $Id$ در فایل به طور خودکار تزریق کنید. + اگر این ویژگی را بر روی یک فایل یا مجموعه‌ای از فایل‌ها تنظیم کنید، سپس دفعه بعد که این شاخه را چک‌اوت کنید، گیت + آن فیلد را با SHA-1 blob جایگزین می‌کند. + مهم است که توجه داشته باشید که این SHA-1 مربوط به کامیت نیست، بلکه مربوط به خود blob است. + خط زیر را در فایل .gitattributes خود قرار دهید:

+
+
+
+
*.txt ident
+
+
+
+

یک مرجع $Id$ به یک فایل آزمایشی اضافه کنید:

+
+
+
+
$ echo '$Id$' > test.txt
+
+
+
+

دفعه بعد که این فایل را چک‌اوت کنید، گیت SHA-1 blob را تزریق می‌کند:

+
+
+
$ rm test.txt
 $ git checkout -- test.txt
 $ cat test.txt
 $Id: 42812b7653c7b88933f8a9d6cad0ca16714b9bb3 $
-
-
-
-

However, that result is of limited use. -If you’ve used keyword substitution in CVS or Subversion, you can include a datestamp – the SHA-1 isn’t all that helpful, because it’s fairly random and you can’t tell if one SHA-1 is older or newer than another just by looking at them.

-
-
-

It turns out that you can write your own filters for doing substitutions in files on commit/checkout. -These are called “clean” and “smudge” filters. -In the .gitattributes file, you can set a filter for particular paths and then set up scripts that will process files just before they’re checked out (“smudge”, see }}">The “smudge” filter is run on checkout.) and just before they’re staged (“clean”, see }}">The “clean” filter is run when files are staged.). -These filters can be set to do all sorts of fun things.

-
-
-
-}}" alt="The ``smudge'' filter is run on checkout."> -
-
نمودار 144. The “smudge” filter is run on checkout.
-
-
-
-}}" alt="The ``clean'' filter is run when files are staged."> -
-
نمودار 145. The “clean” filter is run when files are staged.
-
-
-

The original commit message for this feature gives a simple example of running all your C source code through the indent program before committing. -You can set it up by setting the filter attribute in your .gitattributes file to filter *.c files with the “indent” filter:

-
-
-
-
*.c filter=indent
-
-
-
-

Then, tell Git what the “indent” filter does on smudge and clean:

-
-
-
+
+
+
+

با این حال، آن نتیجه استفاده محدودی دارد. + اگر شما از جایگزینی کلیدواژه در CVS یا Subversion استفاده کرده‌اید، می‌توانید یک تاریخ‌مهر را شامل شوید – SHA-1 + چندان مفید نیست، زیرا نسبتاً تصادفی است و شما نمی‌توانید بگویید که آیا یک SHA-1 قدیمی‌تر یا جدیدتر از دیگری است + فقط با نگاه کردن به آن‌ها.

+
+
+

به نظر می‌رسد که شما می‌توانید فیلترهای خود را برای انجام جایگزینی در فایل‌ها در زمان کامیت/چک‌اوت بنویسید. + این‌ها به عنوان فیلترهای "clean" و "smudge" شناخته می‌شوند. + در فایل .gitattributes، می‌توانید یک فیلتر برای مسیرهای خاص تنظیم کنید و سپس اسکریپت‌هایی را تنظیم + کنید که فایل‌ها را درست قبل از اینکه چک‌اوت شوند ("smudge"، ببینید + }}">The “smudge” filter is run on checkout + ) و درست قبل از اینکه آن‌ها به حالت staging بروند ("clean"، + ببینید + }}">The “clean” filter is run when files are staged). + این فیلترها می‌توانند کارهای جالبی انجام دهند.

+
+
+
+ }}" alt="The “smudge” filter is run on checkout"> +
+
نمودار 144. فیلتر "smudge" در زمان چک‌اوت اجرا می‌شود.
+
+
+
+ }}" alt="The “clean” filter is run when files are staged"> +
+
نمودار 145. فیلتر "clean" در زمان staging اجرا می‌شود.
+
+
+

پیام کامیت اصلی برای این ویژگی یک مثال ساده از اجرای تمام کدهای منبع C از طریق برنامه indent قبل + از کامیت را ارائه می‌دهد. + شما می‌توانید این را با تنظیم ویژگی فیلتر در فایل .gitattributes برای فیلتر *.c با + فیلتر "indent" تنظیم کنید:

+
+
+
+
*.c filter=indent
+
+
+
+

سپس، به گیت بگویید که فیلتر "indent" چه کاری در زمان smudge و clean انجام می‌دهد:

+
+
+
$ git config --global filter.indent.clean indent
 $ git config --global filter.indent.smudge cat
-
-
-
-

In this case, when you commit files that match *.c, Git will run them through the indent program before it stages them and then run them through the cat program before it checks them back out onto disk. -The cat program does essentially nothing: it spits out the same data that it comes in. -This combination effectively filters all C source code files through indent before committing.

-
-
-

Another interesting example gets $Date$ keyword expansion, RCS style. -To do this properly, you need a small script that takes a filename, figures out the last commit date for this project, and inserts the date into the file. -Here is a small Ruby script that does that:

-
-
-
+
+
+
+

در این حالت، زمانی که شما فایل‌هایی که با *.c مطابقت دارند را کامیت می‌کنید، گیت آن‌ها را قبل از + اینکه به حالت staging بروند از طریق برنامه indent اجرا می‌کند و سپس قبل از اینکه دوباره به دیسک چک‌اوت شوند، از + طریق برنامه cat اجرا می‌کند. + برنامه cat اساساً هیچ کاری انجام نمی‌دهد: فقط داده‌هایی را که وارد می‌شود، بازمی‌گرداند. + این ترکیب به طور مؤثر تمام فایل‌های کد منبع C را قبل از کامیت از طریق indent فیلتر می‌کند.

+
+
+

یک مثال جالب دیگر گسترش کلیدواژه $Date$ به سبک RCS است. + برای انجام این کار به درستی، شما به یک اسکریپت کوچک نیاز دارید که نام فایل را بگیرد، آخرین تاریخ کامیت برای این + پروژه را پیدا کند و تاریخ را در آن فایل وارد کند. + در اینجا یک اسکریپت کوچک روبی وجود دارد که این کار را انجام می‌دهد:

+
+
+
#! /usr/bin/env ruby
 data = STDIN.read
 last_date = `git log --pretty=format:"%ad" -1`
 puts data.gsub('$Date$', '$Date: ' + last_date.to_s + '$')
-
-
-
-

All the script does is get the latest commit date from the git log command, stick that into any $Date$ strings it sees in stdin, and print the results – it should be simple to do in whatever language you’re most comfortable in. -You can name this file expand_date and put it in your path. -Now, you need to set up a filter in Git (call it dater) and tell it to use your expand_date filter to smudge the files on checkout. -You’ll use a Perl expression to clean that up on commit:

-
-
-
+
+
+
+

تمام کاری که این اسکریپت انجام می‌دهد این است که آخرین تاریخ کامیت را از دستور git log دریافت + کرده، آن را به هر رشته $Date$ که در stdin می‌بیند، اضافه کرده و نتایج را چاپ می‌کند – باید ساده + باشد که این کار را در هر زبانی که با آن راحت‌تر هستید انجام دهید. + شما می‌توانید این فایل را expand_date نام‌گذاری کرده و در مسیر خود قرار دهید. + اکنون، شما باید یک فیلتر در گیت تنظیم کنید (آن را dater نام‌گذاری کنید) و به آن بگویید که از فیلتر + expand_date شما برای smudge کردن فایل‌ها در زمان چک‌اوت استفاده کند. + شما از یک عبارت Perl برای تمیز کردن آن در زمان کامیت استفاده خواهید کرد:

+
+
+
$ git config filter.dater.smudge expand_date
 $ git config filter.dater.clean 'perl -pe "s/\\\$Date[^\\\$]*\\\$/\\\$Date\\\$/"'
-
-
-
-

This Perl snippet strips out anything it sees in a $Date$ string, to get back to where you started. -Now that your filter is ready, you can test it by setting up a Git attribute for that file that engages the new filter and creating a file with your $Date$ keyword:

-
-
-
-
date*.txt filter=dater
-
-
-
-
-
$ echo '# $Date$' > date_test.txt
-
-
-
-

If you commit those changes and check out the file again, you see the keyword properly substituted:

-
-
-
+
+
+
+

این قطعه Perl هر چیزی را که در یک رشته $Date$ می‌بیند، حذف می‌کند تا به جایی که شروع کردید، + برگردد. + اکنون که فیلتر شما آماده است، می‌توانید آن را با تنظیم یک ویژگی گیت برای آن فایل که فیلتر جدید را فعال می‌کند و + ایجاد یک فایل با کلیدواژه $Date$ آزمایش کنید:

+
+
+
+
date*.txt filter=dater
+
+
+
+
+
$ echo '# $Date$' > date_test.txt
+
+
+
+

اگر شما آن تغییرات را کامیت کنید و دوباره فایل را چک‌اوت کنید، می‌بینید که کلیدواژه به درستی جایگزین شده + است:

+
+
+
$ git add date_test.txt .gitattributes
-$ git commit -m "Test date expansion in Git"
+$ git commit -m "آزمایش گسترش تاریخ در گیت"
 $ rm date_test.txt
 $ git checkout date_test.txt
 $ cat date_test.txt
 # $Date: Tue Apr 21 07:26:52 2009 -0700$
-
-
-
-

You can see how powerful this technique can be for customized applications. -You have to be careful, though, because the .gitattributes file is committed and passed around with the project, but the driver (in this case, dater) isn’t, so it won’t work everywhere. -When you design these filters, they should be able to fail gracefully and have the project still work properly.

-
-
-
-

Exporting Your Repository

-
-

-Git attribute data also allows you to do some interesting things when exporting an archive of your project.

-
-
-

export-ignore

-
-

You can tell Git not to export certain files or directories when generating an archive. -If there is a subdirectory or file that you don’t want to include in your archive file but that you do want checked into your project, you can determine those files via the export-ignore attribute.

-
-
-

For example, say you have some test files in a test/ subdirectory, and it doesn’t make sense to include them in the tarball export of your project. -You can add the following line to your Git attributes file:

-
-
-
-
test/ export-ignore
-
-
-
-

Now, when you run git archive to create a tarball of your project, that directory won’t be included in the archive.

-
-
-
-

export-subst

-
-

When exporting files for deployment you can apply git log's formatting and keyword-expansion processing to selected portions of files marked with the export-subst attribute.

-
-
-

For instance, if you want to include a file named LAST_COMMIT in your project, and have metadata about the last commit automatically injected into it when git archive runs, you can for example set up your .gitattributes and LAST_COMMIT files like this:

-
-
-
-
LAST_COMMIT export-subst
-
-
-
-
-
$ echo 'Last commit date: $Format:%cd by %aN$' > LAST_COMMIT
+      
+
+
+

شما می‌توانید ببینید که این تکنیک چقدر برای برنامه‌های سفارشی قدرتمند است. + با این حال، شما باید مراقب باشید، زیرا فایل .gitattributes کامیت شده و با پروژه منتقل می‌شود، اما + درایور (در این مورد، dater) نیست، بنابراین در همه جا کار نخواهد کرد. + زمانی که شما این فیلترها را طراحی می‌کنید، باید بتوانند به آرامی شکست بخورند و پروژه هنوز به درستی کار کند.

+
+
+
+

صادرات مخزن شما

+
+

+ داده‌های ویژگی‌های گیت همچنین به شما اجازه می‌دهد تا کارهای جالبی هنگام صادرات یک آرشیو از پروژه خود انجام + دهید.

+
+
+

export-ignore

+
+

شما می‌توانید به گیت بگویید که هنگام تولید یک آرشیو، برخی از فایل‌ها یا دایرکتوری‌ها را صادر نکند. + اگر یک زیرپوشه یا فایلی وجود داشته باشد که نمی‌خواهید در فایل آرشیو شما گنجانده شود اما می‌خواهید آن را در + پروژه خود چک کنید، می‌توانید آن فایل‌ها را از طریق ویژگی export-ignore تعیین کنید.

+
+
+

به عنوان مثال، فرض کنید شما برخی از فایل‌های آزمایشی در یک زیرپوشه test/ دارید و منطقی نیست که + آن‌ها را در صادرات tarball پروژه خود گنجانده شود. + شما می‌توانید خط زیر را به فایل ویژگی‌های گیت خود اضافه کنید:

+
+
+
+
test/ export-ignore
+
+
+
+

اکنون، زمانی که شما git archive را اجرا می‌کنید تا یک tarball از پروژه خود ایجاد کنید، آن + دایرکتوری در آرشیو گنجانده نخواهد شد.

+
+
+
+

export-subst

+
+

هنگام صادرات فایل‌ها برای استقرار، می‌توانید پردازش فرمت‌دهی و گسترش کلیدواژه‌های git log را به + بخش‌های انتخاب شده از فایل‌ها که با ویژگی export-subst علامت‌گذاری شده‌اند، اعمال کنید.

+
+
+

به عنوان مثال، اگر می‌خواهید فایلی به نام LAST_COMMIT را در پروژه خود شامل کنید و اطلاعات + متاداده درباره آخرین کامیت به طور خودکار در آن وارد شود زمانی که git archive اجرا می‌شود، + می‌توانید به عنوان مثال فایل‌های .gitattributes و LAST_COMMIT خود را به این صورت + تنظیم کنید:

+
+
+
+
LAST_COMMIT export-subst
+
+
+
+
+
$ echo 'تاریخ آخرین کامیت: $Format:%cd by %aN$' > LAST_COMMIT
 $ git add LAST_COMMIT .gitattributes
-$ git commit -am 'adding LAST_COMMIT file for archives'
-
-
-
-

When you run git archive, the contents of the archived file will look like this:

-
-
-
+$ git commit -am 'اضافه کردن فایل LAST_COMMIT برای آرشیوها' +
+
+
+

زمانی که شما git archive را اجرا می‌کنید، محتوای فایل آرشیو به این صورت خواهد بود:

+
+
+
$ git archive HEAD | tar xCf ../deployment-testing -
 $ cat ../deployment-testing/LAST_COMMIT
-Last commit date: Tue Apr 21 08:38:48 2009 -0700 by Scott Chacon
-
-
-
-

The substitutions can include for example the commit message and any git notes, and git log can do simple word wrapping:

-
-
-
-
$ echo '$Format:Last commit: %h by %aN at %cd%n%+w(76,6,9)%B$' > LAST_COMMIT
-$ git commit -am 'export-subst uses git log'\''s custom formatter
+تاریخ آخرین کامیت: Tue Apr 21 08:38:48 2009 -0700 by Scott Chacon
+
+
+
+

جایگزینی‌ها می‌توانند شامل به عنوان مثال پیام کامیت و هر git notes باشند و git log + می‌تواند کارهای ساده‌ای مانند خط‌پیچی را انجام دهد:

+
+
+
+
$ echo '$Format:آخرین کامیت: %h by %aN at %cd%n%+w(76,6,9)%B$' > LAST_COMMIT
+$ git commit -am 'export-subst از فرمت‌دهی سفارشی git log استفاده می‌کند'
 
-git archive uses git log'\''s `pretty=format:` processor
-directly, and strips the surrounding `$Format:` and `$`
-markup from the output.
+git archive از پردازشگر pretty=format: git log به طور مستقیم استفاده می‌کند
+و علامت‌گذاری محاطی $Format: و $
+را از خروجی حذف می‌کند.
 '
 $ git archive @ | tar xfO - LAST_COMMIT
-Last commit: 312ccc8 by Jim Hill at Fri May 8 09:14:04 2015 -0700
-       export-subst uses git log's custom formatter
-
-         git archive uses git log's `pretty=format:` processor directly, and
-         strips the surrounding `$Format:` and `$` markup from the output.
-
-
-
-

The resulting archive is suitable for deployment work, but like any exported archive it isn’t suitable for further development work.

-
-
-
-
-

Merge Strategies

-
-

-You can also use Git attributes to tell Git to use different merge strategies for specific files in your project. -One very useful option is to tell Git to not try to merge specific files when they have conflicts, but rather to use your side of the merge over someone else’s.

-
-
-

This is helpful if a branch in your project has diverged or is specialized, but you want to be able to merge changes back in from it, and you want to ignore certain files. -Say you have a database settings file called database.xml that is different in two branches, and you want to merge in your other branch without messing up the database file. -You can set up an attribute like this:

-
-
-
-
database.xml merge=ours
-
-
-
-

And then define a dummy ours merge strategy with:

-
-
-
-
$ git config --global merge.ours.driver true
-
-
-
-

If you merge in the other branch, instead of having merge conflicts with the database.xml file, you see something like this:

-
-
-
+آخرین کامیت: 312ccc8 by Jim Hill at Fri May 8 09:14:04 2015 -0700 + export-subst از پردازشگر فرمت‌دهی git log به طور مستقیم استفاده می‌کند +و علامت‌گذاری محاطی $Format: و $ +را از خروجی حذف می‌کند. +
+
+
+

آرشیو حاصل برای کارهای استقرار مناسب است، اما مانند هر آرشیو صادراتی برای کارهای توسعه‌ای مناسب نیست.

+
+
+
+
+

استراتژی‌های ادغام

+
+

+ شما همچنین می‌توانید از ویژگی‌های گیت برای گفتن به گیت استفاده کنید که از استراتژی‌های ادغام مختلف برای فایل‌های + خاص در پروژه شما استفاده کند. + یکی از گزینه‌های بسیار مفید این است که به گیت بگویید که در صورت بروز تضاد، سعی نکند فایل‌های خاصی را ادغام کند، + بلکه از طرف شما در ادغام استفاده کند.

+
+
+

این مفید است اگر یک شاخه در پروژه شما انحراف داشته باشد یا تخصصی باشد، اما می‌خواهید بتوانید تغییرات را از آن + ادغام کنید و می‌خواهید برخی از فایل‌ها را نادیده بگیرید. + فرض کنید شما یک فایل تنظیمات پایگاه داده به نام database.xml دارید که در دو شاخه متفاوت است و + می‌خواهید تغییرات را از شاخه دیگر ادغام کنید بدون اینکه فایل پایگاه داده را خراب کنید. + شما می‌توانید ویژگی‌ای مانند این را تنظیم کنید:

+
+
+
+
database.xml merge=ours
+
+
+
+

و سپس یک استراتژی ادغام جعلی ours را با:

+
+
+
+
$ git config --global merge.ours.driver true
+
+
+
+

اگر شما تغییرات را از شاخه دیگر ادغام کنید، به جای اینکه تضادهای ادغامی با فایل database.xml داشته + باشید، چیزی شبیه به این را خواهید دید:

+
+
+
$ git merge topic
 Auto-merging database.xml
 Merge made by recursive.
-
-
-
-

In this case, database.xml stays at whatever version you originally had.

-
-
- \ No newline at end of file +
+
+
+

در این حالت، database.xml در هر نسخه‌ای که شما در ابتدا داشتید باقی می‌ماند.

+
+
+ +
\ No newline at end of file diff --git a/external/book/content/book/fa/v2/Customizing-Git-Git-Configuration.html b/external/book/content/book/fa/v2/Customizing-Git-Git-Configuration.html index d7d2a7280a..21608d79c0 100644 --- a/external/book/content/book/fa/v2/Customizing-Git-Git-Configuration.html +++ b/external/book/content/book/fa/v2/Customizing-Git-Git-Configuration.html @@ -17,374 +17,439 @@ next: book/fa/v2/Customizing-Git-Git-Attributes title: Git - Git Configuration --- -

So far, we’ve covered the basics of how Git works and how to use it, and we’ve introduced a number of tools that Git provides to help you use it easily and efficiently. -In this chapter, we’ll see how you can make Git operate in a more customized fashion, by introducing several important configuration settings and the hooks system. -With these tools, it’s easy to get Git to work exactly the way you, your company, or your group needs it to.

-

Git Configuration

-
-

-As you read briefly in }}">شروع به کار, you can specify Git configuration settings with the git config command. -One of the first things you did was set up your name and email address:

-
-
-
-
$ git config --global user.name "John Doe"
+
+

تا کنون، ما اصول اولیه کارکرد گیت و نحوه استفاده از آن را پوشش داده‌ایم و تعدادی از ابزارهایی که گیت برای کمک به + شما در استفاده آسان و کارآمد از آن فراهم می‌کند را معرفی کرده‌ایم. + در این فصل، خواهیم دید که چگونه می‌توانید گیت را به شیوه‌ای سفارشی‌تر اجرا کنید، با معرفی چندین تنظیمات پیکربندی مهم + و سیستم هوک‌ها. + با این ابزارها، آسان است که گیت را دقیقاً به شیوه‌ای که شما، شرکت شما یا گروه شما نیاز دارد، کار کند.

+

پیکربندی گیت

+
+

+ همانطور که به طور مختصر در + }}">Getting Started + خواندید، می‌توانید تنظیمات پیکربندی گیت را با دستور git config مشخص کنید. + یکی از اولین کارهایی که انجام دادید، تنظیم نام و آدرس ایمیل شما بود:

+
+
+
+
$ git config --global user.name "جان دو"
 $ git config --global user.email johndoe@example.com
-
-
-
-

Now you’ll learn a few of the more interesting options that you can set in this manner to customize your Git usage.

-
-
-

First, a quick review: Git uses a series of configuration files to determine non-default behavior that you may want. -The first place Git looks for these values is in the system-wide /etc/gitconfig file, which contains settings that are applied to every user on the system and all of their repositories. -If you pass the option --system to git config, it reads and writes from this file specifically.

-
-
-

The next place Git looks is the ~/.gitconfig (or ~/.config/git/config) file, which is specific to each user. -You can make Git read and write to this file by passing the --global option.

-
-
-

Finally, Git looks for configuration values in the configuration file in the Git directory (.git/config) of whatever repository you’re currently using. -These values are specific to that single repository, and represent passing the --local option to git config. -(If you don’t specify which level you want to work with, this is the default.)

-
-
-

Each of these “levels” (system, global, local) overwrites values in the previous level, so values in .git/config trump those in /etc/gitconfig, for instance.

-
-
- - - - - -
-
یادداشت
-
-
-

Git’s configuration files are plain-text, so you can also set these values by manually editing the file and inserting the correct syntax. -It’s generally easier to run the git config command, though.

-
-
-
-
-

Basic Client Configuration

-
-

The configuration options recognized by Git fall into two categories: client-side and server-side. -The majority of the options are client-side — configuring your personal working preferences. -Many, many configuration options are supported, but a large fraction of them are useful only in certain edge cases; we’ll cover just the most common and useful options here. -If you want to see a list of all the options your version of Git recognizes, you can run

-
-
-
-
$ man git-config
-
-
-
-

This command lists all the available options in quite a bit of detail. -You can also find this reference material at https://git-scm.com/docs/git-config.

-
-
-

core.editor

-
-

-By default, Git uses whatever you’ve set as your default text editor via one of the shell environment variables VISUAL or EDITOR, or else falls back to the vi editor to create and edit your commit and tag messages. -To change that default to something else, you can use the core.editor setting:

-
-
-
-
$ git config --global core.editor emacs
-
-
-
-

Now, no matter what is set as your default shell editor, Git will fire up Emacs to edit messages.

-
-
-
-

commit.template

-
-

-If you set this to the path of a file on your system, Git will use that file as the default initial message when you commit. -The value in creating a custom commit template is that you can use it to remind yourself (or others) of the proper format and style when creating a commit message.

-
-
-

For instance, consider a template file at ~/.gitmessage.txt that looks like this:

-
-
-
-
Subject line (try to keep under 50 characters)
+    
+
+
+

اکنون چند گزینه جالب‌تر را یاد خواهید گرفت که می‌توانید به این روش برای سفارشی‌سازی استفاده از گیت تنظیم + کنید.

+
+
+

اول، یک مرور سریع: گیت از مجموعه‌ای از فایل‌های پیکربندی برای تعیین رفتار غیر پیش‌فرضی که ممکن است بخواهید + استفاده می‌کند. + اولین جایی که گیت به دنبال این مقادیر می‌گردد، فایل پیکربندی سیستم‌گسترده /etc/gitconfig است که شامل + تنظیماتی است که به هر کاربر در سیستم و تمام مخازن آن‌ها اعمال می‌شود. + اگر گزینه --system را به git config بدهید، به طور خاص از این فایل خوانده و نوشته می‌شود. +

+
+
+

جای بعدی که گیت به دنبال آن می‌گردد، فایل ~/.gitconfig (یا ~/.config/git/config) است که + مختص هر کاربر است. + می‌توانید با دادن گزینه --global به گیت بگویید که از این فایل بخواند و بنویسد.

+
+
+

در نهایت، گیت به دنبال مقادیر پیکربندی در فایل پیکربندی در دایرکتوری گیت (.git/config) از هر مخزنی + که در حال حاضر استفاده می‌کنید، می‌گردد. + این مقادیر مختص آن مخزن خاص هستند و نمایانگر دادن گزینه --local به git config هستند. + (اگر مشخص نکنید که می‌خواهید با کدام سطح کار کنید، این پیش‌فرض است.)

+
+
+

هر یک از این "سطوح" (سیستم، جهانی، محلی) مقادیر سطح قبلی را بازنویسی می‌کند، بنابراین مقادیر در + .git/config بر مقادیر در /etc/gitconfig ارجحیت دارند، به عنوان مثال.

+
+
+ + + + + +
+
یادداشت
+
+
+

فایل‌های پیکربندی گیت متن‌ساده هستند، بنابراین می‌توانید این مقادیر را با ویرایش دستی فایل و وارد کردن + نحو صحیح نیز تنظیم کنید. + با این حال، معمولاً راحت‌تر است که دستور git config را اجرا کنید.

+
+
+
+
+

پیکربندی پایه کلاینت

+
+

گزینه‌های پیکربندی که گیت شناسایی می‌کند به دو دسته تقسیم می‌شوند: سمت کلاینت و سمت سرور. + اکثر گزینه‌ها سمت کلاینت هستند — تنظیم ترجیحات کاری شخصی شما. + بسیاری، بسیاری از گزینه‌های پیکربندی پشتیبانی می‌شوند، اما بخش بزرگی از آن‌ها فقط در موارد خاص مفید + هستند؛ ما فقط رایج‌ترین و مفیدترین گزینه‌ها را در اینجا پوشش خواهیم داد. + اگر می‌خواهید فهرستی از تمام گزینه‌هایی که نسخه شما از گیت شناسایی می‌کند را ببینید، می‌توانید این دستور را اجرا + کنید:

+
+
+
+
$ man git-config
+
+
+
+

این دستور تمام گزینه‌های موجود را با جزئیات کافی فهرست می‌کند. + شما همچنین می‌توانید این مطالب مرجع را در https://git-scm.com/docs/git-config + پیدا کنید.

+
+
+

core.editor

+
+

+ به طور پیش‌فرض، گیت از هر چیزی که به عنوان ویرایشگر متن پیش‌فرض خود از طریق یکی از متغیرهای محیطی شل VISUAL + یا EDITOR تنظیم کرده‌اید، استفاده می‌کند، و در غیر این صورت به ویرایشگر vi برای + ایجاد و ویرایش پیام‌های کامیت و برچسب‌ها بازمی‌گردد. + برای تغییر این پیش‌فرض به چیز دیگری، می‌توانید از تنظیم core.editor استفاده کنید:

+
+
+
+
$ git config --global core.editor emacs
+
+
+
+

اکنون، مهم نیست که چه چیزی به عنوان ویرایشگر شل پیش‌فرض شما تنظیم شده باشد، گیت برای ویرایش پیام‌ها، Emacs را + باز می‌کند.

+
+
+
+

commit.template

+
+

+ اگر این را به مسیر یک فایل در سیستم خود تنظیم کنید، گیت از آن فایل به عنوان پیام اولیه پیش‌فرض هنگام کامیت + استفاده خواهد کرد. + ارزش ایجاد یک الگوی کامیت سفارشی این است که می‌توانید از آن برای یادآوری خود (یا دیگران) در مورد فرمت و سبک + مناسب هنگام ایجاد یک پیام کامیت استفاده کنید.

+
+
+

به عنوان مثال، یک فایل الگو در ~/.gitmessage.txt که به این شکل باشد:

+
+
+
+
خط موضوع (سعی کنید زیر 50 کاراکتر نگه دارید)
 
-Multi-line description of commit,
-feel free to be detailed.
+توضیحات چند خطی از کامیت،
+احساس راحتی کنید که جزئیات بیشتری اضافه کنید.
 
-[Ticket: X]
-
-
-
-

Note how this commit template reminds the committer to keep the subject line short (for the sake of git log --oneline output), to add further detail under that, and to refer to an issue or bug tracker ticket number if one exists.

-
-
-

To tell Git to use it as the default message that appears in your editor when you run git commit, set the commit.template configuration value:

-
-
-
+[تیکت: X]
+
+
+
+

به یاد داشته باشید که این الگوی کامیت به کامیت‌کننده یادآوری می‌کند که خط موضوع را کوتاه نگه دارد (برای خروجی + git log --oneline)، جزئیات بیشتری زیر آن اضافه کند و اگر تیکتی وجود دارد، به شماره تیکت یا ردیاب + اشکال اشاره کند.

+
+
+

برای اینکه به گیت بگویید از آن به عنوان پیام پیش‌فرضی که هنگام اجرای git commit در ویرایشگر شما + ظاهر می‌شود استفاده کند، مقدار پیکربندی commit.template را تنظیم کنید:

+
+
+
$ git config --global commit.template ~/.gitmessage.txt
 $ git commit
-
-
-
-

Then, your editor will open to something like this for your placeholder commit message when you commit:

-
-
-
-
Subject line (try to keep under 50 characters)
+        
+
+
+

سپس، ویرایشگر شما برای پیام کامیت جایگزین شما به چیزی شبیه به این باز خواهد شد:

+
+
+
+
خط موضوع (سعی کنید زیر 50 کاراکتر نگه دارید)
 
-Multi-line description of commit,
-feel free to be detailed.
+توضیحات چند خطی از کامیت،
+احساس راحتی کنید که جزئیات بیشتری اضافه کنید.
 
-[Ticket: X]
-# Please enter the commit message for your changes. Lines starting
-# with '#' will be ignored, and an empty message aborts the commit.
-# On branch master
-# Changes to be committed:
-#   (use "git reset HEAD <file>..." to unstage)
+[تیکت: X]
+# لطفاً پیام کامیت خود را برای تغییرات خود وارد کنید. خطوطی که با
+# '#' شروع می‌شوند نادیده گرفته می‌شوند و یک پیام خالی کامیت را لغو می‌کند.
+# در شاخه master
+# تغییرات برای کامیت:
+#   (از "git reset HEAD <file>..." برای لغو انتخاب استفاده کنید)
 #
-# modified:   lib/test.rb
+# تغییر یافته:   lib/test.rb
 #
 ~
 ~
 ".git/COMMIT_EDITMSG" 14L, 297C
-
-
-
-

If your team has a commit-message policy, then putting a template for that policy on your system and configuring Git to use it by default can help increase the chance of that policy being followed regularly.

-
- -
-

core.pager

-
-

-This setting determines which pager is used when Git pages output such as log and diff. -You can set it to more or to your favorite pager (by default, it’s less), or you can turn it off by setting it to a blank string:

-
-
-
-
$ git config --global core.pager ''
-
-
-
-

If you run that, Git will page the entire output of all commands, no matter how long they are.

-
-
-
-

user.signingkey

-
-

-If you’re making signed annotated tags (as discussed in }}">Signing Your Work), setting your GPG signing key as a configuration setting makes things easier. -Set your key ID like so:

-
-
-
-
$ git config --global user.signingkey <gpg-key-id>
-
-
-
-

Now, you can sign tags without having to specify your key every time with the git tag command:

-
-
-
-
$ git tag -s <tag-name>
-
-
-
-
-

core.excludesfile

-
-

-You can put patterns in your project’s .gitignore file to have Git not see them as untracked files or try to stage them when you run git add on them, as discussed in }}">نادیده گرفتن فایل‌ها.

-
-
-

But sometimes you want to ignore certain files for all repositories that you work with. -If your computer is running macOS, you’re probably familiar with .DS_Store files. -If your preferred editor is Emacs or Vim, you know about filenames that end with a ~ or .swp.

-
-
-

This setting lets you write a kind of global .gitignore file. -If you create a ~/.gitignore_global file with these contents:

-
-
-
+
+
+
+

اگر تیم شما یک سیاست پیام کامیت دارد، قرار دادن یک الگو برای آن سیاست در سیستم شما و پیکربندی گیت برای + استفاده از آن به طور پیش‌فرض می‌تواند به افزایش احتمال پیروی از آن سیاست کمک کند.

+
+
+
+

core.pager

+
+

+ این تنظیم تعیین می‌کند که کدام صفحه‌گردان هنگام خروجی گیت مانند log و diff استفاده + می‌شود. + می‌توانید آن را به more یا به صفحه‌گردان مورد علاقه خود (به طور پیش‌فرض، less) تنظیم + کنید، یا می‌توانید با تنظیم آن به یک رشته خالی آن را خاموش کنید:

+
+
+
+
$ git config --global core.pager ''
+
+
+
+

اگر این کار را انجام دهید، گیت تمام خروجی تمام دستورات را صفحه‌بندی می‌کند، مهم نیست که چقدر طولانی + هستند.

+
+
+
+

user.signingkey

+
+

+ اگر شما برچسب‌های امضا شده و حاشیه‌نویسی شده ایجاد می‌کنید (همانطور که در + }}">Signing Your Work + بحث شده است)، تنظیم کلید امضای GPG شما به عنوان یک تنظیم پیکربندی کار را آسان‌تر + می‌کند. + کلید ID خود را به این شکل تنظیم کنید:

+
+
+
+
$ git config --global user.signingkey <gpg-key-id>
+
+
+
+

اکنون، می‌توانید برچسب‌ها را بدون نیاز به مشخص کردن کلید خود هر بار با دستور git tag امضا کنید: +

+
+
+
+
$ git tag -s <tag-name>
+
+
+
+
+

core.excludesfile

+
+

+ می‌توانید الگوهایی را در فایل .gitignore پروژه خود قرار دهید تا گیت آن‌ها را به عنوان فایل‌های + بدون ردیابی نبیند یا سعی نکند آن‌ها را هنگام اجرای git add بر روی آن‌ها انتخاب کند، همانطور که در + }}">Ignoring Files بحث شده است.

+
+
+

اما گاهی اوقات می‌خواهید برخی از فایل‌ها را برای تمام مخازن که با آن‌ها کار می‌کنید نادیده بگیرید. + اگر کامپیوتر شما در حال اجرای macOS است، احتمالاً با فایل‌های .DS_Store آشنا هستید. + اگر ویرایشگر مورد علاقه شما Emacs یا Vim است، درباره نام فایل‌هایی که با ~ یا .swp + پایان می‌یابند، می‌دانید.

+
+
+

این تنظیم به شما اجازه می‌دهد نوعی فایل .gitignore جهانی بنویسید. + اگر یک فایل ~/.gitignore_global با این محتویات ایجاد کنید:

+
+
+
*~
 .*.swp
 .DS_Store
-
-
-
-

…and you run git config --global core.excludesfile ~/.gitignore_global, Git will never again bother you about those files.

-
-
-
-

help.autocorrect

-
-

-If you mistype a command, it shows you something like this:

-
-
-
+
+
+
+

…و دستور git config --global core.excludesfile ~/.gitignore_global را اجرا کنید، گیت دیگر هرگز + شما را در مورد آن فایل‌ها آزار نخواهد داد.

+
+
+
+

help.autocorrect

+
+

+ اگر یک دستور را اشتباه تایپ کنید، چیزی شبیه به این به شما نشان می‌دهد:

+
+
+
$ git chekcout master
 git: 'chekcout' is not a git command. See 'git --help'.
 
-Did you mean this?
+آیا منظور شما این بود؟
     checkout
-
-
-
-

Git helpfully tries to figure out what you meant, but it still refuses to do it. -If you set help.autocorrect to 1, Git will actually run this command for you:

-
-
-
+
+
+
+

گیت به طور مفید سعی می‌کند بفهمد که منظور شما چه بوده، اما هنوز هم از انجام آن امتناع می‌کند. + اگر help.autocorrect را به 1 تنظیم کنید، گیت واقعاً این دستور را برای شما اجرا خواهد کرد:

+
+
+
$ git chekcout master
 WARNING: You called a Git command named 'chekcout', which does not exist.
 Continuing under the assumption that you meant 'checkout'
 in 0.1 seconds automatically...
-
-
-
-

Note that “0.1 seconds” business. -help.autocorrect is actually an integer which represents tenths of a second. -So if you set it to 50, Git will give you 5 seconds to change your mind before executing the autocorrected command.

-
-
- -
-

Colors in Git

-
-

-Git fully supports colored terminal output, which greatly aids in visually parsing command output quickly and easily. -A number of options can help you set the coloring to your preference.

-
-
-

color.ui

-
-

Git automatically colors most of its output, but there’s a master switch if you don’t like this behavior. -To turn off all Git’s colored terminal output, do this:

-
-
-
-
$ git config --global color.ui false
-
-
-
-

The default setting is auto, which colors output when it’s going straight to a terminal, but omits the color-control codes when the output is redirected to a pipe or a file.

-
-
-

You can also set it to always to ignore the difference between terminals and pipes. -You’ll rarely want this; in most scenarios, if you want color codes in your redirected output, you can instead pass a --color flag to the Git command to force it to use color codes. -The default setting is almost always what you’ll want.

-
-
-
-

color.*

-
-

If you want to be more specific about which commands are colored and how, Git provides verb-specific coloring settings. -Each of these can be set to true, false, or always:

-
-
-
+
+
+
+

به یاد داشته باشید که این "0.1 ثانیه" است. + help.autocorrect در واقع یک عدد صحیح است که نمایانگر دهم‌های ثانیه است. + بنابراین اگر آن را به 50 تنظیم کنید، گیت به شما 5 ثانیه زمان می‌دهد تا قبل از اجرای دستور اصلاح شده، نظر خود + را تغییر دهید.

+
+
+
+
+

رنگ‌ها در گیت

+
+

+ گیت به طور کامل از خروجی رنگی ترمینال پشتیبانی می‌کند، که به طور قابل توجهی در تجزیه بصری خروجی دستورات به سرعت + و به آسانی کمک می‌کند. + تعدادی از گزینه‌ها می‌توانند به شما کمک کنند تا رنگ‌آمیزی را به سلیقه خود تنظیم کنید.

+
+
+

color.ui

+
+

گیت به طور خودکار بیشتر خروجی‌های خود را رنگ‌آمیزی می‌کند، اما یک سوئیچ اصلی وجود دارد اگر این رفتار را + نپسندید. + برای خاموش کردن تمام خروجی رنگی ترمینال گیت، این کار را انجام دهید:

+
+
+
+
$ git config --global color.ui false
+
+
+
+

تنظیم پیش‌فرض auto است، که خروجی را زمانی که به طور مستقیم به یک ترمینال می‌رود رنگ‌آمیزی + می‌کند، اما کدهای کنترل رنگ را زمانی که خروجی به یک لوله یا فایل هدایت می‌شود، حذف می‌کند.

+
+
+

شما همچنین می‌توانید آن را به always تنظیم کنید تا تفاوت بین ترمینال‌ها و لوله‌ها را نادیده + بگیرد. + شما به ندرت این کار را خواهید کرد؛ در بیشتر سناریوها، اگر می‌خواهید کدهای رنگی در خروجی هدایت شده خود داشته + باشید، می‌توانید به جای آن یک پرچم --color به دستور گیت بدهید تا مجبور به استفاده از کدهای رنگی + شود. + تنظیم پیش‌فرض تقریباً همیشه چیزی است که شما می‌خواهید.

+
+
+
+

color.*

+
+

اگر می‌خواهید دقیق‌تر در مورد اینکه کدام دستورات رنگی هستند و چگونه، گیت تنظیمات رنگی خاصی برای افعال ارائه + می‌دهد. + هر یک از این‌ها می‌تواند به true، false یا always تنظیم شود:

+
+
+
color.branch
 color.diff
 color.interactive
 color.status
-
-
-
-

In addition, each of these has subsettings you can use to set specific colors for parts of the output, if you want to override each color. -For example, to set the meta information in your diff output to blue foreground, black background, and bold text, you can run

-
-
-
-
$ git config --global color.diff.meta "blue black bold"
-
-
-
-

You can set the color to any of the following values: normal, black, red, green, yellow, blue, magenta, cyan, or white. -If you want an attribute like bold in the previous example, you can choose from bold, dim, ul (underline), blink, and reverse (swap foreground and background).

-
-
-
-
-

External Merge and Diff Tools

-
-

-Although Git has an internal implementation of diff, which is what we’ve been showing in this book, you can set up an external tool instead. -You can also set up a graphical merge-conflict-resolution tool instead of having to resolve conflicts manually. -We’ll demonstrate setting up the Perforce Visual Merge Tool (P4Merge) to do your diffs and merge resolutions, because it’s a nice graphical tool and it’s free.

-
-
-

If you want to try this out, P4Merge works on all major platforms, so you should be able to do so. -We’ll use path names in the examples that work on macOS and Linux systems; for Windows, you’ll have to change /usr/local/bin to an executable path in your environment.

-
-
-

To begin, download P4Merge from Perforce. -Next, you’ll set up external wrapper scripts to run your commands. -We’ll use the macOS path for the executable; in other systems, it will be where your p4merge binary is installed. -Set up a merge wrapper script named extMerge that calls your binary with all the arguments provided:

-
-
-
+
+
+
+

علاوه بر این، هر یک از این‌ها دارای زیرتنظیماتی است که می‌توانید برای تنظیم رنگ‌های خاص برای بخش‌های خروجی + استفاده کنید، اگر بخواهید هر رنگ را بازنویسی کنید. + به عنوان مثال، برای تنظیم اطلاعات متا در خروجی diff خود به رنگ پیش‌زمینه آبی، پس‌زمینه سیاه و متن بولد، + می‌توانید این دستور را اجرا کنید:

+
+
+
+
$ git config --global color.diff.meta "blue black bold"
+
+
+
+

شما می‌توانید رنگ را به هر یک از مقادیر زیر تنظیم کنید: normal، black، + red، green، yellow، blue، magenta، + cyan، یا white. + اگر می‌خواهید ویژگی‌ای مانند بولد در مثال قبلی داشته باشید، می‌توانید از bold، dim، + ul (زیرخط)، blink و reverse (معکوس کردن پیش‌زمینه و پس‌زمینه) انتخاب + کنید.

+
+
+ +
+

ابزارهای ادغام و تفاوت خارجی

+
+

+ اگرچه گیت یک پیاده‌سازی داخلی از diff دارد، که ما در این کتاب نشان داده‌ایم، می‌توانید به جای آن یک ابزار خارجی + تنظیم کنید. + شما همچنین می‌توانید یک ابزار گرافیکی برای حل تعارضات ادغام تنظیم کنید به جای اینکه مجبور باشید تعارضات را به + صورت دستی حل کنید. + ما تنظیم ابزار ادغام بصری Perforce (P4Merge) را برای انجام تفاوت‌ها و حل ادغام‌ها نشان خواهیم داد، زیرا این یک + ابزار گرافیکی خوب و رایگان است.

+
+
+

اگر می‌خواهید این را امتحان کنید، P4Merge در تمام پلتفرم‌های اصلی کار می‌کند، بنابراین باید بتوانید این کار را + انجام دهید. + ما از نام‌های مسیر در مثال‌ها استفاده خواهیم کرد که در سیستم‌های macOS و Linux کار می‌کنند؛ برای ویندوز، باید + /usr/local/bin را به یک مسیر اجرایی در محیط خود تغییر دهید.

+
+
+

برای شروع، P4Merge + را از Perforce دانلود کنید. + سپس، شما اسکریپت‌های wrapper خارجی را برای اجرای دستورات خود تنظیم خواهید کرد. + ما از مسیر macOS برای اجرایی استفاده خواهیم کرد؛ در سیستم‌های دیگر، این جایی خواهد بود که باینری + p4merge شما نصب شده است. + یک اسکریپت wrapper ادغام به نام extMerge تنظیم کنید که باینری شما را با تمام آرگومان‌های ارائه شده + فراخوانی کند:

+
+
+
$ cat /usr/local/bin/extMerge
 #!/bin/sh
 /Applications/p4merge.app/Contents/MacOS/p4merge $*
-
-
-
-

The diff wrapper checks to make sure seven arguments are provided and passes two of them to your merge script. -By default, Git passes the following arguments to the diff program:

-
-
-
-
path old-file old-hex old-mode new-file new-hex new-mode
-
-
-
-

Because you only want the old-file and new-file arguments, you use the wrapper script to pass the ones you need.

-
-
-
+
+
+
+

wrapper diff بررسی می‌کند که آیا هفت آرگومان ارائه شده است و دو تا از آن‌ها را به اسکریپت ادغام شما منتقل + می‌کند. + به طور پیش‌فرض، گیت آرگومان‌های زیر را به برنامه diff منتقل می‌کند:

+
+
+
+
path old-file old-hex old-mode new-file new-hex new-mode
+
+
+
+

زیرا شما فقط می‌خواهید آرگومان‌های old-file و new-file را داشته باشید، از اسکریپت + wrapper برای انتقال آن‌هایی که نیاز دارید استفاده می‌کنید.

+
+
+
$ cat /usr/local/bin/extDiff
 #!/bin/sh
 [ $# -eq 7 ] && /usr/local/bin/extMerge "$2" "$5"
-
-
-
-

You also need to make sure these tools are executable:

-
-
-
+
+
+
+

شما همچنین باید مطمئن شوید که این ابزارها قابل اجرا هستند:

+
+
+
$ sudo chmod +x /usr/local/bin/extMerge
 $ sudo chmod +x /usr/local/bin/extDiff
-
-
-
-

Now you can set up your config file to use your custom merge resolution and diff tools. -This takes a number of custom settings: merge.tool to tell Git what strategy to use, mergetool.<tool>.cmd to specify how to run the command, mergetool.<tool>.trustExitCode to tell Git if the exit code of that program indicates a successful merge resolution or not, and diff.external to tell Git what command to run for diffs. -So, you can either run four config commands

-
-
-
+
+
+
+

اکنون می‌توانید فایل پیکربندی خود را برای استفاده از ابزارهای سفارشی ادغام و تفاوت خود تنظیم کنید. + این نیاز به تعدادی تنظیمات سفارشی دارد: merge.tool برای گفتن به گیت که از چه استراتژی استفاده کند، + mergetool.<tool>.cmd برای مشخص کردن نحوه اجرای دستور، mergetool.<tool>.trustExitCode + برای گفتن به گیت که آیا کد خروج آن برنامه نشان‌دهنده یک ادغام موفق است یا خیر، و diff.external برای + گفتن به گیت که چه دستوری را برای تفاوت‌ها اجرا کند. + بنابراین، می‌توانید چهار دستور پیکربندی را اجرا کنید

+
+
+
$ git config --global merge.tool extMerge
 $ git config --global mergetool.extMerge.cmd \
   'extMerge "$BASE" "$LOCAL" "$REMOTE" "$MERGED"'
 $ git config --global mergetool.extMerge.trustExitCode false
 $ git config --global diff.external extDiff
-
-
-
-

or you can edit your ~/.gitconfig file to add these lines:

-
-
-
+
+
+
+

یا می‌توانید فایل ~/.gitconfig خود را ویرایش کنید تا این خطوط را اضافه کنید:

+
+
+
[merge]
   tool = extMerge
 [mergetool "extMerge"]
@@ -392,50 +457,53 @@ 

External Merge and Diff Tools

trustExitCode = false [diff] external = extDiff
-
-
-
-

After all this is set, if you run diff commands such as this:

-
-
-
-
$ git diff 32d1776b1^ 32d1776b1
-
-
-
-

Instead of getting the diff output on the command line, Git fires up P4Merge, which looks something like this:

-
-
-
-}}" alt="P4Merge."> -
-
نمودار 143. P4Merge.
-
-
-

If you try to merge two branches and subsequently have merge conflicts, you can run the command git mergetool; it starts P4Merge to let you resolve the conflicts through that GUI tool.

-
-
-

The nice thing about this wrapper setup is that you can change your diff and merge tools easily. -For example, to change your extDiff and extMerge tools to run the KDiff3 tool instead, all you have to do is edit your extMerge file:

-
-
-
+
+
+
+

پس از تنظیم همه این‌ها، اگر دستورات diff مانند این را اجرا کنید:

+
+
+
+
$ git diff 32d1776b1^ 32d1776b1
+
+
+
+

به جای دریافت خروجی diff در خط فرمان، گیت P4Merge را راه‌اندازی می‌کند که چیزی شبیه به این خواهد بود:

+
+
+
+ }}" alt="P4Merge"> +
+
نمودار 143. P4Merge.
+
+
+

اگر سعی کنید دو شاخه را ادغام کنید و سپس تعارضات ادغام داشته باشید، می‌توانید دستور git mergetool + را اجرا کنید؛ این ابزار P4Merge را برای حل تعارضات از طریق آن ابزار GUI راه‌اندازی می‌کند.

+
+
+

نکته خوب در مورد این تنظیمات wrapper این است که می‌توانید ابزارهای تفاوت و ادغام خود را به راحتی تغییر دهید. + به عنوان مثال، برای تغییر ابزارهای extDiff و extMerge به KDiff3، تنها کاری که باید + انجام دهید ویرایش فایل extMerge است:

+
+
+
$ cat /usr/local/bin/extMerge
 #!/bin/sh
 /Applications/kdiff3.app/Contents/MacOS/kdiff3 $*
-
-
-
-

Now, Git will use the KDiff3 tool for diff viewing and merge conflict resolution.

-
-
-

Git comes preset to use a number of other merge-resolution tools without your having to set up the cmd configuration. -To see a list of the tools it supports, try this:

-
-
-
+
+
+
+

اکنون، گیت از ابزار KDiff3 برای مشاهده تفاوت‌ها و حل تعارضات ادغام استفاده خواهد کرد.

+
+
+

گیت به طور پیش‌فرض برای استفاده از تعدادی از ابزارهای دیگر حل تعارضات ادغام بدون نیاز به تنظیم پیکربندی cmd + آماده است. + برای دیدن فهرستی از ابزارهایی که پشتیبانی می‌کند، این کار را امتحان کنید:

+
+
+
$ git mergetool --tool-help
-'git mergetool --tool=<tool>' may be set to one of the following:
+'git mergetool --tool=<tool>' ممکن است به یکی از موارد زیر تنظیم شود:
         emerge
         gvimdiff
         gvimdiff2
@@ -444,7 +512,7 @@ 

External Merge and Diff Tools

vimdiff vimdiff2 -The following tools are valid, but not currently available: +ابزارهای زیر معتبر هستند، اما در حال حاضر در دسترس نیستند: araxis bc3 codecompare @@ -458,181 +526,224 @@

External Merge and Diff Tools

tortoisemerge xxdiff -Some of the tools listed above only work in a windowed -environment. If run in a terminal-only session, they will fail.
-
-
-
-

If you’re not interested in using KDiff3 for diff but rather want to use it just for merge resolution, and the kdiff3 command is in your path, then you can run

-
-
-
-
$ git config --global merge.tool kdiff3
-
-
-
-

If you run this instead of setting up the extMerge and extDiff files, Git will use KDiff3 for merge resolution and the normal Git diff tool for diffs.

-
-
-
-

Formatting and Whitespace

-
-

-Formatting and whitespace issues are some of the more frustrating and subtle problems that many developers encounter when collaborating, especially cross-platform. -It’s very easy for patches or other collaborated work to introduce subtle whitespace changes because editors silently introduce them, and if your files ever touch a Windows system, their line endings might be replaced. -Git has a few configuration options to help with these issues.

-
-
-

core.autocrlf

-
-

-If you’re programming on Windows and working with people who are not (or vice-versa), you’ll probably run into line-ending issues at some point. -This is because Windows uses both a carriage-return character and a linefeed character for newlines in its files, whereas macOS and Linux systems use only the linefeed character. -This is a subtle but incredibly annoying fact of cross-platform work; many editors on Windows silently replace existing LF-style line endings with CRLF, or insert both line-ending characters when the user hits the enter key.

-
-
-

Git can handle this by auto-converting CRLF line endings into LF when you add a file to the index, and vice versa when it checks out code onto your filesystem. -You can turn on this functionality with the core.autocrlf setting. -If you’re on a Windows machine, set it to true — this converts LF endings into CRLF when you check out code:

-
-
-
-
$ git config --global core.autocrlf true
-
-
-
-

If you’re on a Linux or macOS system that uses LF line endings, then you don’t want Git to automatically convert them when you check out files; however, if a file with CRLF endings accidentally gets introduced, then you may want Git to fix it. -You can tell Git to convert CRLF to LF on commit but not the other way around by setting core.autocrlf to input:

-
-
-
-
$ git config --global core.autocrlf input
-
-
-
-

This setup should leave you with CRLF endings in Windows checkouts, but LF endings on macOS and Linux systems and in the repository.

-
-
-

If you’re a Windows programmer doing a Windows-only project, then you can turn off this functionality, recording the carriage returns in the repository by setting the config value to false:

-
-
-
-
$ git config --global core.autocrlf false
-
-
-
-
-

core.whitespace

-
-

Git comes preset to detect and fix some whitespace issues. -It can look for six primary whitespace issues — three are enabled by default and can be turned off, and three are disabled by default but can be activated.

-
-
-

The three that are turned on by default are blank-at-eol, which looks for spaces at the end of a line; blank-at-eof, which notices blank lines at the end of a file; and space-before-tab, which looks for spaces before tabs at the beginning of a line.

-
-
-

The three that are disabled by default but can be turned on are indent-with-non-tab, which looks for lines that begin with spaces instead of tabs (and is controlled by the tabwidth option); tab-in-indent, which watches for tabs in the indentation portion of a line; and cr-at-eol, which tells Git that carriage returns at the end of lines are OK.

-
-
-

You can tell Git which of these you want enabled by setting core.whitespace to the values you want on or off, separated by commas. -You can disable an option by prepending a - in front of its name, or use the default value by leaving it out of the setting string entirely. -For example, if you want all but space-before-tab to be set, you can do this (with trailing-space being a short-hand to cover both blank-at-eol and blank-at-eof):

-
-
-
+برخی از ابزارهای ذکر شده در بالا فقط در یک محیط دارای پنجره کار می‌کنند. اگر در یک جلسه فقط ترمینال اجرا شوند، شکست خواهند خورد. +
+
+
+

اگر به استفاده از KDiff3 برای تفاوت‌ها علاقه‌مند نیستید، بلکه فقط می‌خواهید از آن برای حل ادغام استفاده کنید و + دستور kdiff3 در مسیر شما قرار دارد، می‌توانید این دستور را اجرا کنید:

+
+
+
+
$ git config --global merge.tool kdiff3
+
+
+
+

اگر این کار را به جای تنظیم فایل‌های extMerge و extDiff انجام دهید، گیت از KDiff3 + برای حل ادغام و از ابزار diff عادی گیت برای تفاوت‌ها استفاده خواهد کرد.

+
+
+
+

فرمت‌بندی و فاصله‌گذاری

+
+

+ مسائل فرمت‌بندی و فاصله‌گذاری برخی از مشکلات آزاردهنده و ظریف هستند که بسیاری از توسعه‌دهندگان هنگام همکاری با + آن‌ها مواجه می‌شوند، به ویژه در کارهای چندپلتفرمی. + بسیار آسان است که وصله‌ها یا سایر کارهای مشترک تغییرات ظریف فاصله‌گذاری را معرفی کنند زیرا ویرایشگرها به طور + خاموش آن‌ها را وارد می‌کنند، و اگر فایل‌های شما هرگز با یک سیستم ویندوزی تماس پیدا کنند، ممکن است انتهای خط + آن‌ها جایگزین شود. + گیت چند گزینه پیکربندی برای کمک به این مسائل دارد.

+
+
+

core.autocrlf

+
+

+ اگر شما در ویندوز برنامه‌نویسی می‌کنید و با افرادی که این کار را نمی‌کنند (یا برعکس) کار می‌کنید، احتمالاً در + یک نقطه با مسائل انتهای خط مواجه خواهید شد. + این به این دلیل است که ویندوز از هر دو کاراکتر بازگشت به کاراکتر و کاراکتر خط جدید برای انتهای خط در فایل‌های + خود استفاده می‌کند، در حالی که سیستم‌های macOS و Linux فقط از کاراکتر خط جدید استفاده می‌کنند. + این یک واقعیت ظریف اما فوق‌العاده آزاردهنده در کارهای چندپلتفرمی است؛ بسیاری از ویرایشگرها در ویندوز به طور + خاموش انتهای خط‌های LF موجود را با CRLF جایگزین می‌کنند، یا هر دو کاراکتر انتهای خط را زمانی که کاربر کلید + Enter را فشار می‌دهد، وارد می‌کنند.

+
+
+

گیت می‌تواند این را با تبدیل خودکار انتهای خط CRLF به LF هنگام افزودن یک فایل به ایندکس و بالعکس هنگام چک‌اوت + کد به سیستم فایل شما مدیریت کند. + می‌توانید این قابلیت را با تنظیم core.autocrlf فعال کنید. + اگر در یک ماشین ویندوز هستید، آن را به true تنظیم کنید — این انتهای LF را به CRLF تبدیل می‌کند + زمانی که کد را چک‌اوت می‌کنید:

+
+
+
+
$ git config --global core.autocrlf true
+
+
+
+

اگر در یک سیستم Linux یا macOS هستید که از انتهای LF استفاده می‌کند، پس نمی‌خواهید گیت به طور خودکار آن‌ها را + هنگام چک‌اوت فایل‌ها تبدیل کند؛ با این حال، اگر فایلی با انتهای CRLF به طور تصادفی معرفی شود، ممکن است بخواهید + گیت آن را اصلاح کند. + می‌توانید به گیت بگویید که CRLF را به LF در کامیت تبدیل کند اما نه بالعکس با تنظیم core.autocrlf + به input:

+
+
+
+
$ git config --global core.autocrlf input
+
+
+
+

این تنظیم باید به شما اجازه دهد که انتهای CRLF را در چک‌اوت‌های ویندوز داشته باشید، اما انتهای LF را در + سیستم‌های macOS و Linux و در مخزن داشته باشید.

+
+
+

اگر شما یک برنامه‌نویس ویندوز هستید که پروژه‌ای فقط برای ویندوز انجام می‌دهید، می‌توانید این قابلیت را خاموش + کنید و بازگشت‌های کاراکتر را در مخزن با تنظیم مقدار پیکربندی به false ثبت کنید:

+
+
+
+
$ git config --global core.autocrlf false
+
+
+
+
+

core.whitespace

+
+

گیت به طور پیش‌فرض برای شناسایی و اصلاح برخی از مسائل فاصله‌گذاری تنظیم شده است. + می‌تواند به دنبال شش مشکل اصلی فاصله‌گذاری باشد — سه مورد به طور پیش‌فرض فعال هستند و می‌توانند خاموش شوند، و + سه مورد به طور پیش‌فرض غیرفعال هستند اما می‌توانند فعال شوند.

+
+
+

سه موردی که به طور پیش‌فرض فعال هستند blank-at-eol است، که به دنبال فضاها در انتهای یک خط + می‌گردد؛ blank-at-eof، که خطوط خالی در انتهای یک فایل را شناسایی می‌کند؛ و + space-before-tab، که به دنبال فضاها قبل از تب‌ها در ابتدای یک خط می‌گردد.

+
+
+

سه موردی که به طور پیش‌فرض غیرفعال هستند اما می‌توانند فعال شوند indent-with-non-tab است، که به + دنبال خطوطی می‌گردد که با فضاها به جای تب‌ها شروع می‌شوند (و توسط گزینه tabwidth کنترل می‌شود)؛ + tab-in-indent، که به دنبال تب‌ها در بخش فاصله‌گذاری یک خط می‌گردد؛ و cr-at-eol، که + به گیت می‌گوید که بازگشت‌های کاراکتر در انتهای خطوط اشکالی ندارد.

+
+
+

می‌توانید به گیت بگویید که کدام یک از این‌ها را می‌خواهید با تنظیم core.whitespace به مقادیر + مورد نظر خود روشن یا خاموش کنید، که با کاما جدا شده‌اند. + می‌توانید یک گزینه را با پیشوند - در جلوی نام آن غیرفعال کنید، یا با حذف آن از رشته تنظیم به ارزش + پیش‌فرض برگردید. + به عنوان مثال، اگر می‌خواهید همه به جز space-before-tab تنظیم شوند، می‌توانید این کار را انجام + دهید (با trailing-space که به عنوان یک کوتاه‌نویس برای پوشش هر دو blank-at-eol و + blank-at-eof است):

+
+
+
$ git config --global core.whitespace \
     trailing-space,-space-before-tab,indent-with-non-tab,tab-in-indent,cr-at-eol
-
-
-
-

Or you can specify the customizing part only:

-
-
-
+
+
+
+

یا می‌توانید فقط قسمت سفارشی‌سازی را مشخص کنید:

+
+
+
$ git config --global core.whitespace \
     -space-before-tab,indent-with-non-tab,tab-in-indent,cr-at-eol
-
-
-
-

Git will detect these issues when you run a git diff command and try to color them so you can possibly fix them before you commit. -It will also use these values to help you when you apply patches with git apply. -When you’re applying patches, you can ask Git to warn you if it’s applying patches with the specified whitespace issues:

-
-
-
-
$ git apply --whitespace=warn <patch>
-
-
-
-

Or you can have Git try to automatically fix the issue before applying the patch:

-
-
-
-
$ git apply --whitespace=fix <patch>
-
-
-
-

These options apply to the git rebase command as well. -If you’ve committed whitespace issues but haven’t yet pushed upstream, you can run git rebase --whitespace=fix to have Git automatically fix whitespace issues as it’s rewriting the patches.

-
-
-
-
-

Server Configuration

-
-

Not nearly as many configuration options are available for the server side of Git, but there are a few interesting ones you may want to take note of.

-
-
-

receive.fsckObjects

-
-

Git is capable of making sure every object received during a push still matches its SHA-1 checksum and points to valid objects. -However, it doesn’t do this by default; it’s a fairly expensive operation, and might slow down the operation, especially on large repositories or pushes. -If you want Git to check object consistency on every push, you can force it to do so by setting receive.fsckObjects to true:

-
-
-
-
$ git config --system receive.fsckObjects true
-
-
-
-

Now, Git will check the integrity of your repository before each push is accepted to make sure faulty (or malicious) clients aren’t introducing corrupt data.

-
-
-
-

receive.denyNonFastForwards

-
-

If you rebase commits that you’ve already pushed and then try to push again, or otherwise try to push a commit to a remote branch that doesn’t contain the commit that the remote branch currently points to, you’ll be denied. -This is generally good policy; but in the case of the rebase, you may determine that you know what you’re doing and can force-update the remote branch with a -f flag to your push command.

-
-
-

To tell Git to refuse force-pushes, set receive.denyNonFastForwards:

-
-
-
-
$ git config --system receive.denyNonFastForwards true
-
-
-
-

The other way you can do this is via server-side receive hooks, which we’ll cover in a bit. -That approach lets you do more complex things like deny non-fast-forwards to a certain subset of users.

-
-
-
-

receive.denyDeletes

-
-

One of the workarounds to the denyNonFastForwards policy is for the user to delete the branch and then push it back up with the new reference. -To avoid this, set receive.denyDeletes to true:

-
-
-
-
$ git config --system receive.denyDeletes true
-
-
-
-

This denies any deletion of branches or tags — no user can do it. -To remove remote branches, you must remove the ref files from the server manually. -There are also more interesting ways to do this on a per-user basis via ACLs, as you’ll learn in }}">An Example Git-Enforced Policy.

-
-
-
- \ No newline at end of file +
+ +
+

گیت این مسائل را زمانی که دستور git diff را اجرا می‌کنید شناسایی می‌کند و سعی می‌کند آن‌ها را + رنگ‌آمیزی کند تا بتوانید قبل از کامیت آن‌ها را اصلاح کنید. + همچنین از این مقادیر برای کمک به شما هنگام اعمال وصله‌ها با git apply استفاده خواهد کرد. + هنگامی که وصله‌ها را اعمال می‌کنید، می‌توانید از گیت بخواهید که اگر وصله‌هایی با مسائل فاصله‌گذاری مشخص شده را + اعمال می‌کند، به شما هشدار دهد:

+
+
+
+
$ git apply --whitespace=warn <patch>
+
+
+
+

یا می‌توانید از گیت بخواهید که قبل از اعمال وصله، سعی کند مشکل را به طور خودکار اصلاح کند:

+
+
+
+
$ git apply --whitespace=fix <patch>
+
+
+
+

این گزینه‌ها همچنین به دستور git rebase اعمال می‌شوند. + اگر شما مسائل فاصله‌گذاری را کامیت کرده‌اید اما هنوز به بالا فشار نداده‌اید، می‌توانید دستور git rebase + --whitespace=fix را اجرا کنید تا گیت به طور خودکار مسائل فاصله‌گذاری را در حین بازنویسی وصله‌ها اصلاح + کند.

+
+ + +
+

پیکربندی سرور

+
+

گزینه‌های پیکربندی برای سمت سرور گیت به مراتب کمتر از آنچه که در سمت کلاینت وجود دارد، هستند، اما چند گزینه + جالب وجود دارد که ممکن است بخواهید به آن‌ها توجه کنید.

+
+
+

receive.fsckObjects

+
+

گیت قادر است اطمینان حاصل کند که هر شیء دریافتی در حین یک فشار هنوز با checksum SHA-1 خود مطابقت دارد و به + اشیاء معتبر اشاره می‌کند. + با این حال، به طور پیش‌فرض این کار را انجام نمی‌دهد؛ این یک عملیات نسبتاً پرهزینه است و ممکن است عملیات را کند + کند، به ویژه در مخازن یا فشارهای بزرگ. + اگر می‌خواهید گیت در هر فشار، سازگاری اشیاء را بررسی کند، می‌توانید با تنظیم receive.fsckObjects + به true این کار را مجبور کنید:

+
+
+
+
$ git config --system receive.fsckObjects true
+
+
+
+

اکنون، گیت قبل از پذیرش هر فشار، یکپارچگی مخزن شما را بررسی می‌کند تا مطمئن شود که مشتریان معیوب (یا مخرب) + داده‌های خراب را معرفی نمی‌کنند.

+
+
+
+

receive.denyNonFastForwards

+
+

اگر شما کامیت‌هایی را که قبلاً فشار داده‌اید بازنویسی کنید و سپس سعی کنید دوباره فشار دهید، یا به طور دیگر + سعی کنید یک کامیت را به یک شاخه از راه دور فشار دهید که شامل کامیتی نیست که شاخه از راه دور در حال حاضر به آن + اشاره می‌کند، شما رد خواهید شد. + این معمولاً سیاست خوبی است؛ اما در مورد بازنویسی، ممکن است تشخیص دهید که می‌دانید چه می‌کنید و می‌توانید با + پرچم -f به دستور فشار خود، شاخه از راه دور را به‌روزرسانی کنید.

+
+
+

برای اینکه به گیت بگویید که از پذیرش فشارهای اجباری امتناع کند، receive.denyNonFastForwards را + تنظیم کنید:

+
+
+
+
$ git config --system receive.denyNonFastForwards true
+
+
+
+

روش دیگر برای انجام این کار از طریق هوک‌های دریافت سمت سرور است، که در ادامه به آن خواهیم پرداخت. + این رویکرد به شما اجازه می‌دهد کارهای پیچیده‌تری مانند رد کردن غیرپیشرفته‌ها برای یک زیرمجموعه خاص از کاربران + را انجام دهید.

+
+
+
+

receive.denyDeletes

+
+

یکی از راه‌حل‌های دور زدن سیاست denyNonFastForwards این است که کاربر شاخه را حذف کند و سپس آن را + با مرجع جدید فشار دهد. + برای جلوگیری از این کار، receive.denyDeletes را به true تنظیم کنید:

+
+
+
+
$ git config --system receive.denyDeletes true
+
+
+
+

این هر گونه حذف شاخه‌ها یا برچسب‌ها را رد می‌کند — هیچ کاربری نمی‌تواند این کار را انجام دهد. + برای حذف شاخه‌های از راه دور، باید فایل‌های ref را به صورت دستی از سرور حذف کنید. + همچنین روش‌های جالب‌تری برای انجام این کار به صورت کاربر به کاربر از طریق ACLها وجود دارد، همانطور که در + }}">An Example Git-Enforced Policy + خواهید آموخت.

+
+
+
+ + \ No newline at end of file diff --git a/external/book/content/book/fa/v2/Customizing-Git-Git-Hooks.html b/external/book/content/book/fa/v2/Customizing-Git-Git-Hooks.html index dd79c9d904..0b591c5e86 100644 --- a/external/book/content/book/fa/v2/Customizing-Git-Git-Hooks.html +++ b/external/book/content/book/fa/v2/Customizing-Git-Git-Hooks.html @@ -17,168 +17,170 @@ next: book/fa/v2/Customizing-Git-An-Example-Git-Enforced-Policy title: Git - Git Hooks --- -

Git Hooks

+
+

هوک‌های گیت

-

-Like many other Version Control Systems, Git has a way to fire off custom scripts when certain important actions occur. -There are two groups of these hooks: client-side and server-side. -Client-side hooks are triggered by operations such as committing and merging, while server-side hooks run on network operations such as receiving pushed commits. -You can use these hooks for all sorts of reasons.

+

+ مانند بسیاری از سیستم‌های کنترل نسخه دیگر، گیت راهی برای اجرای اسکریپت‌های سفارشی هنگام وقوع برخی از اقدامات مهم دارد. + این هوک‌ها به دو گروه تقسیم می‌شوند: هوک‌های سمت کلاینت و هوک‌های سمت سرور. + هوک‌های سمت کلاینت توسط عملیاتی مانند کامیت و ادغام فعال می‌شوند، در حالی که هوک‌های سمت سرور در عملیات شبکه مانند دریافت کامیت‌های ارسال شده اجرا می‌شوند. + شما می‌توانید از این هوک‌ها برای انواع مختلفی از دلایل استفاده کنید.

-

Installing a Hook

-
-

The hooks are all stored in the hooks subdirectory of the Git directory. -In most projects, that’s .git/hooks. -When you initialize a new repository with git init, Git populates the hooks directory with a bunch of example scripts, many of which are useful by themselves; but they also document the input values of each script. -All the examples are written as shell scripts, with some Perl thrown in, but any properly named executable scripts will work fine – you can write them in Ruby or Python or whatever language you are familiar with. -If you want to use the bundled hook scripts, you’ll have to rename them; their file names all end with .sample.

-
-
-

To enable a hook script, put a file in the hooks subdirectory of your .git directory that is named appropriately (without any extension) and is executable. -From that point forward, it should be called. -We’ll cover most of the major hook filenames here.

-
+

نصب یک هوک

+
+

تمام هوک‌ها در زیرپوشه hooks دایرکتوری گیت ذخیره می‌شوند. + در بیشتر پروژه‌ها، این دایرکتوری .git/hooks است. + زمانی که شما یک مخزن جدید با git init راه‌اندازی می‌کنید، گیت دایرکتوری هوک را با تعدادی اسکریپت نمونه پر می‌کند که بسیاری از آن‌ها به خودی خود مفید هستند؛ اما همچنین ورودی‌های هر اسکریپت را مستند می‌کنند. + تمام مثال‌ها به عنوان اسکریپت‌های شل نوشته شده‌اند، با مقداری پرل در آن‌ها، اما هر اسکریپت اجرایی با نام مناسب به خوبی کار خواهد کرد – شما می‌توانید آن‌ها را به زبان روبی یا پایتون یا هر زبانی که با آن آشنا هستید بنویسید. + اگر می‌خواهید از اسکریپت‌های هوک بسته‌بندی شده استفاده کنید، باید نام آن‌ها را تغییر دهید؛ نام فایل‌های آن‌ها همه با .sample پایان می‌یابد.

+
+
+

برای فعال‌سازی یک اسکریپت هوک، فایلی را در زیرپوشه hooks دایرکتوری .git خود قرار دهید که به طور مناسب نام‌گذاری شده باشد (بدون هیچ پسوندی) و قابل اجرا باشد. + از آن نقطه به بعد، باید فراخوانی شود. + ما در اینجا بیشتر نام‌های هوک‌های اصلی را پوشش خواهیم داد.

+
-

Client-Side Hooks

-
-

There are a lot of client-side hooks. -This section splits them into committing-workflow hooks, email-workflow scripts, and everything else.

-
-
- - - - - -
-
یادداشت
-
-
-

It’s important to note that client-side hooks are not copied when you clone a repository. -If your intent with these scripts is to enforce a policy, you’ll probably want to do that on the server side; see the example in }}">An Example Git-Enforced Policy.

-
-
-
-
-

Committing-Workflow Hooks

-
-

The first four hooks have to do with the committing process.

-
-
-

The pre-commit hook is run first, before you even type in a commit message. -It’s used to inspect the snapshot that’s about to be committed, to see if you’ve forgotten something, to make sure tests run, or to examine whatever you need to inspect in the code. -Exiting non-zero from this hook aborts the commit, although you can bypass it with git commit --no-verify. -You can do things like check for code style (run lint or something equivalent), check for trailing whitespace (the default hook does exactly this), or check for appropriate documentation on new methods.

-
-
-

The prepare-commit-msg hook is run before the commit message editor is fired up but after the default message is created. -It lets you edit the default message before the commit author sees it. -This hook takes a few parameters: the path to the file that holds the commit message so far, the type of commit, and the commit SHA-1 if this is an amended commit. -This hook generally isn’t useful for normal commits; rather, it’s good for commits where the default message is auto-generated, such as templated commit messages, merge commits, squashed commits, and amended commits. -You may use it in conjunction with a commit template to programmatically insert information.

-
-
-

The commit-msg hook takes one parameter, which again is the path to a temporary file that contains the commit message written by the developer. -If this script exits non-zero, Git aborts the commit process, so you can use it to validate your project state or commit message before allowing a commit to go through. -In the last section of this chapter, we’ll demonstrate using this hook to check that your commit message is conformant to a required pattern.

-
-
-

After the entire commit process is completed, the post-commit hook runs. -It doesn’t take any parameters, but you can easily get the last commit by running git log -1 HEAD. -Generally, this script is used for notification or something similar.

-
-
-
-

Email Workflow Hooks

-
-

You can set up three client-side hooks for an email-based workflow. -They’re all invoked by the git am command, so if you aren’t using that command in your workflow, you can safely skip to the next section. -If you’re taking patches over email prepared by git format-patch, then some of these may be helpful to you.

-
-
-

The first hook that is run is applypatch-msg. -It takes a single argument: the name of the temporary file that contains the proposed commit message. -Git aborts the patch if this script exits non-zero. -You can use this to make sure a commit message is properly formatted, or to normalize the message by having the script edit it in place.

-
-
-

The next hook to run when applying patches via git am is pre-applypatch. -Somewhat confusingly, it is run after the patch is applied but before a commit is made, so you can use it to inspect the snapshot before making the commit. -You can run tests or otherwise inspect the working tree with this script. -If something is missing or the tests don’t pass, exiting non-zero aborts the git am script without committing the patch.

-
-
-

The last hook to run during a git am operation is post-applypatch, which runs after the commit is made. -You can use it to notify a group or the author of the patch you pulled in that you’ve done so. -You can’t stop the patching process with this script.

-
-
-
-

Other Client Hooks

-
-

The pre-rebase hook runs before you rebase anything and can halt the process by exiting non-zero. -You can use this hook to disallow rebasing any commits that have already been pushed. -The example pre-rebase hook that Git installs does this, although it makes some assumptions that may not match with your workflow.

-
-
-

The post-rewrite hook is run by commands that replace commits, such as git commit --amend and git rebase (though not by git filter-branch). -Its single argument is which command triggered the rewrite, and it receives a list of rewrites on stdin. -This hook has many of the same uses as the post-checkout and post-merge hooks.

-
-
-

After you run a successful git checkout, the post-checkout hook runs; you can use it to set up your working directory properly for your project environment. -This may mean moving in large binary files that you don’t want source controlled, auto-generating documentation, or something along those lines.

-
-
-

The post-merge hook runs after a successful merge command. -You can use it to restore data in the working tree that Git can’t track, such as permissions data. -This hook can likewise validate the presence of files external to Git control that you may want copied in when the working tree changes.

-
-
-

The pre-push hook runs during git push, after the remote refs have been updated but before any objects have been transferred. -It receives the name and location of the remote as parameters, and a list of to-be-updated refs through stdin. -You can use it to validate a set of ref updates before a push occurs (a non-zero exit code will abort the push).

-
-
-

Git occasionally does garbage collection as part of its normal operation, by invoking git gc --auto. -The pre-auto-gc hook is invoked just before the garbage collection takes place, and can be used to notify you that this is happening, or to abort the collection if now isn’t a good time.

-
-
+

هوک‌های سمت کلاینت

+
+

هوک‌های زیادی در سمت کلاینت وجود دارد. + این بخش آن‌ها را به هوک‌های جریان کاری کامیت، اسکریپت‌های جریان کاری ایمیل و سایر موارد تقسیم می‌کند.

+
+
+ + + + + +
+
یادداشت
+
+
+

مهم است که توجه داشته باشید که هوک‌های سمت کلاینت کپی نمی‌شوند زمانی که شما یک مخزن را کلون می‌کنید. + اگر هدف شما از این اسکریپت‌ها تحمیل یک سیاست است، احتمالاً می‌خواهید این کار را در سمت سرور انجام دهید؛ به مثال در }}">یک مثال از سیاست تحمیلی گیت مراجعه کنید.

+
+
+
+
+

هوک‌های جریان کاری کامیت

+
+

چهار هوک اول مربوط به فرآیند کامیت هستند.

+
+
+

هوک pre-commit ابتدا اجرا می‌شود، قبل از اینکه شما حتی یک پیام کامیت وارد کنید. + این هوک برای بررسی نمایه‌ای که قرار است کامیت شود، استفاده می‌شود تا ببیند آیا چیزی را فراموش کرده‌اید، اطمینان حاصل کند که تست‌ها اجرا می‌شوند، یا هر چیزی که نیاز دارید در کد بررسی کنید. + خروجی غیرصفر از این هوک کامیت را متوقف می‌کند، اگرچه می‌توانید با git commit --no-verify آن را دور بزنید. + شما می‌توانید کارهایی مانند بررسی سبک کد (اجرا کردن lint یا چیزی معادل آن)، بررسی فاصله‌های اضافی (هوک پیش‌فرض دقیقاً همین کار را انجام می‌دهد)، یا بررسی مستندات مناسب در مورد متدهای جدید انجام دهید.

+
+
+

هوک prepare-commit-msg قبل از اینکه ویرایشگر پیام کامیت باز شود اما بعد از ایجاد پیام پیش‌فرض اجرا می‌شود. + این هوک به شما اجازه می‌دهد تا پیام پیش‌فرض را قبل از اینکه نویسنده کامیت آن را ببیند ویرایش کنید. + این هوک چند پارامتر می‌گیرد: مسیر فایلی که پیام کامیت را تا کنون نگه می‌دارد، نوع کامیت و SHA-1 کامیت اگر این یک کامیت اصلاح شده باشد. + این هوک معمولاً برای کامیت‌های عادی مفید نیست؛ بلکه برای کامیت‌هایی که پیام پیش‌فرض به صورت خودکار تولید می‌شود، مانند پیام‌های کامیت الگو، کامیت‌های ادغام، کامیت‌های فشرده و کامیت‌های اصلاح شده خوب است. + شما می‌توانید از آن به همراه یک الگوی کامیت برای به‌طور برنامه‌نویسی اطلاعات را وارد کنید.

+
+
+

هوک commit-msg یک پارامتر می‌گیرد، که دوباره مسیر یک فایل موقت است که شامل پیام کامیت نوشته شده توسط توسعه‌دهنده است. + اگر این اسکریپت خروجی غیرصفر داشته باشد، گیت فرآیند کامیت را متوقف می‌کند، بنابراین می‌توانید از آن برای اعتبارسنجی وضعیت پروژه یا پیام کامیت خود قبل از اجازه دادن به کامیت استفاده کنید. + در بخش آخر این فصل، ما استفاده از این هوک را برای بررسی اینکه آیا پیام کامیت شما با یک الگوی مورد نیاز مطابقت دارد، نشان خواهیم داد.

+
+
+

پس از اتمام کل فرآیند کامیت، هوک post-commit اجرا می‌شود. + این هوک هیچ پارامتری نمی‌گیرد، اما می‌توانید به راحتی آخرین کامیت را با اجرای git log -1 HEAD به دست آورید. + به طور کلی، این اسکریپت برای اطلاع‌رسانی یا چیزی مشابه استفاده می‌شود.

+
+
+
+

هوک‌های جریان کاری ایمیل

+
+

شما می‌توانید سه هوک سمت کلاینت برای یک جریان کاری مبتنی بر ایمیل تنظیم کنید. + همه آن‌ها توسط دستور git am فراخوانی می‌شوند، بنابراین اگر شما از آن دستور در جریان کاری خود استفاده نمی‌کنید، می‌توانید با خیال راحت به بخش بعدی بروید. + اگر شما پچ‌ها را از طریق ایمیل که با git format-patch آماده شده‌اند، می‌گیرید، برخی از این‌ها ممکن است برای شما مفید باشند.

+
+
+

اولین هوکی که اجرا می‌شود applypatch-msg است. + این هوک یک آرگومان می‌گیرد: نام فایل موقتی که شامل پیام کامیت پیشنهادی است. + اگر این اسکریپت خروجی غیرصفر داشته باشد، گیت پچ را رد می‌کند. + شما می‌توانید از این هوک برای اطمینان از اینکه پیام کامیت به درستی فرمت شده است، یا برای نرمال‌سازی پیام با ویرایش آن در محل استفاده کنید.

+
+
+

هوک بعدی که هنگام اعمال پچ‌ها از طریق git am اجرا می‌شود pre-applypatch است. + به طرز گیج‌کننده‌ای، این هوک بعد از اینکه پچ اعمال شد اما قبل از اینکه کامیت انجام شود، اجرا می‌شود، بنابراین می‌توانید از آن برای بررسی نمایه قبل از انجام کامیت استفاده کنید. + شما می‌توانید با این اسکریپت تست‌ها را اجرا کنید یا به هر نحوی نمایه کاری را بررسی کنید. + اگر چیزی کم باشد یا تست‌ها پاس نشوند، خروجی غیرصفر، اسکریپت git am را بدون کامیت کردن پچ متوقف می‌کند.

+
+
+

آخرین هوکی که در حین عملیات git am اجرا می‌شود post-applypatch است که بعد از انجام کامیت اجرا می‌شود. + شما می‌توانید از آن برای اطلاع‌رسانی به یک گروه یا نویسنده پچ که شما آن را وارد کرده‌اید، استفاده کنید. + شما نمی‌توانید با این اسکریپت فرآیند پچ را متوقف کنید.

+
+
+
+

سایر هوک‌های کلاینت

+
+

هوک pre-rebase قبل از اینکه شما هر چیزی را بازنویسی کنید اجرا می‌شود و می‌تواند فرآیند را با خروجی غیرصفر متوقف کند. + شما می‌توانید از این هوک برای جلوگیری از بازنویسی هر کامیتی که قبلاً ارسال شده است، استفاده کنید. + هوک pre-rebase نمونه‌ای که گیت نصب می‌کند این کار را انجام می‌دهد، اگرچه برخی فرضیات را انجام می‌دهد که ممکن است با جریان کاری شما مطابقت نداشته باشد.

+
+
+

هوک post-rewrite توسط دستوراتی که کامیت‌ها را جایگزین می‌کنند، مانند git commit --amend و git rebase (اگرچه نه توسط git filter-branch) اجرا می‌شود. + آرگومان واحد آن این است که کدام دستور باعث بازنویسی شده است و لیستی از بازنویسی‌ها را در stdin دریافت می‌کند. + این هوک بسیاری از همان کاربردها را دارد که هوک‌های post-checkout و post-merge دارند.

+
+
+

پس از اینکه شما یک git checkout موفق را اجرا کردید، هوک post-checkout اجرا می‌شود؛ شما می‌توانید از آن برای تنظیم دایرکتوری کاری خود به درستی برای محیط پروژه‌تان استفاده کنید. + این ممکن است به معنای جابجایی فایل‌های باینری بزرگ باشد که نمی‌خواهید تحت کنترل منبع باشند، تولید خودکار مستندات، یا چیزی در این راستا باشد.

+
+
+

هوک post-merge پس از یک دستور merge موفق اجرا می‌شود. + شما می‌توانید از آن برای بازیابی داده‌ها در نمایه کاری که گیت نمی‌تواند ردیابی کند، مانند داده‌های مجوز استفاده کنید. + این هوک همچنین می‌تواند وجود فایل‌های خارجی که ممکن است بخواهید در هنگام تغییر نمایه کاری کپی شوند را اعتبارسنجی کند.

+
+
+

هوک pre-push در حین git push اجرا می‌شود، پس از اینکه مراجع راه دور به‌روزرسانی شده‌اند اما قبل از اینکه هیچ شیئی منتقل شود. + این هوک نام و مکان راه دور را به عنوان پارامترها دریافت می‌کند و لیستی از مراجع به‌روزرسانی شده را از طریق stdin دریافت می‌کند. + شما می‌توانید از آن برای اعتبارسنجی مجموعه‌ای از به‌روزرسانی‌های مرجع قبل از وقوع یک پش استفاده کنید (کد خروج غیرصفر، پش را متوقف می‌کند).

+
+
+

گیت به طور دوره‌ای جمع‌آوری زباله را به عنوان بخشی از عملیات عادی خود انجام می‌دهد، با فراخوانی git gc --auto. + هوک pre-auto-gc درست قبل از انجام جمع‌آوری زباله فراخوانی می‌شود و می‌تواند برای اطلاع‌رسانی به شما که این اتفاق در حال وقوع است، یا برای متوقف کردن جمع‌آوری در صورتی که اکنون زمان مناسبی نیست، استفاده شود.

+
+
-

Server-Side Hooks

-
-

In addition to the client-side hooks, you can use a couple of important server-side hooks as a system administrator to enforce nearly any kind of policy for your project. -These scripts run before and after pushes to the server. -The pre hooks can exit non-zero at any time to reject the push as well as print an error message back to the client; you can set up a push policy that’s as complex as you wish.

-
-
-

pre-receive

-
-

The first script to run when handling a push from a client is pre-receive. -It takes a list of references that are being pushed from stdin; if it exits non-zero, none of them are accepted. -You can use this hook to do things like make sure none of the updated references are non-fast-forwards, or to do access control for all the refs and files they’re modifying with the push.

-
-
-
-

update

-
-

The update script is very similar to the pre-receive script, except that it’s run once for each branch the pusher is trying to update. -If the pusher is trying to push to multiple branches, pre-receive runs only once, whereas update runs once per branch they’re pushing to. -Instead of reading from stdin, this script takes three arguments: the name of the reference (branch), the SHA-1 that reference pointed to before the push, and the SHA-1 the user is trying to push. -If the update script exits non-zero, only that reference is rejected; other references can still be updated.

-
-
-
-

post-receive

-
-

The post-receive hook runs after the entire process is completed and can be used to update other services or notify users. -It takes the same stdin data as the pre-receive hook. -Examples include emailing a list, notifying a continuous integration server, or updating a ticket-tracking system – you can even parse the commit messages to see if any tickets need to be opened, modified, or closed. -This script can’t stop the push process, but the client doesn’t disconnect until it has completed, so be careful if you try to do anything that may take a long time.

-
-
-
- \ No newline at end of file +

هوک‌های سمت سرور

+
+

علاوه بر هوک‌های سمت کلاینت، شما می‌توانید به عنوان یک مدیر سیستم از چند هوک مهم سمت سرور برای تحمیل تقریباً هر نوع سیاستی برای پروژه خود استفاده کنید. + این اسکریپت‌ها قبل و بعد از پش‌ها به سرور اجرا می‌شوند. + هوک‌های پیش می‌توانند در هر زمان با خروجی غیرصفر پش را رد کنند و همچنین می‌توانند پیام خطای خود را به کلاینت چاپ کنند؛ شما می‌توانید یک سیاست پش تنظیم کنید که به پیچیدگی دلخواه شما باشد.

+
+
+

pre-receive

+
+

اولین اسکریپت که هنگام پردازش یک پش از یک کلاینت اجرا می‌شود pre-receive است. + این هوک لیستی از مراجع را که از stdin پش می‌شوند، می‌گیرد؛ اگر خروجی غیرصفر داشته باشد، هیچ‌کدام از آن‌ها پذیرفته نمی‌شوند. + شما می‌توانید از این هوک برای کارهایی مانند اطمینان از اینکه هیچ‌یک از مراجع به‌روزرسانی شده غیر پیشرفته نیستند، یا برای انجام کنترل دسترسی برای تمام مراجع و فایل‌هایی که با پش تغییر می‌کنند، استفاده کنید.

+
+
+
+

update

+
+

اسکریپت update بسیار مشابه اسکریپت pre-receive است، با این تفاوت که یک بار برای هر شاخه‌ای که پش‌کننده سعی دارد به‌روزرسانی کند، اجرا می‌شود. + اگر پش‌کننده سعی کند به چندین شاخه پش کند، pre-receive فقط یک بار اجرا می‌شود، در حالی که update یک بار برای هر شاخه‌ای که به آن پش می‌شود، اجرا می‌شود. + به جای خواندن از stdin، این اسکریپت سه آرگومان می‌گیرد: نام مرجع (شاخه)، SHA-1 که مرجع قبل از پش به آن اشاره می‌کرد، و SHA-1 که کاربر سعی دارد پش کند. + اگر اسکریپت update خروجی غیرصفر داشته باشد، فقط آن مرجع رد می‌شود؛ مراجع دیگر همچنان می‌توانند به‌روزرسانی شوند.

+
+
+
+

post-receive

+
+

هوک post-receive پس از اتمام کل فرآیند اجرا می‌شود و می‌تواند برای به‌روزرسانی خدمات دیگر یا اطلاع‌رسانی به کاربران استفاده شود. + این هوک همان داده‌های stdin را به عنوان هوک pre-receive می‌گیرد. + مثال‌ها شامل ارسال ایمیل به یک لیست، اطلاع‌رسانی به یک سرور یکپارچه‌سازی مداوم، یا به‌روزرسانی یک سیستم ردیابی بلیط است – شما حتی می‌توانید پیام‌های کامیت را تجزیه کنید تا ببینید آیا بلیط‌هایی وجود دارند که باید باز، ویرایش یا بسته شوند. + این اسکریپت نمی‌تواند فرآیند پش را متوقف کند، اما کلاینت تا زمانی که این فرآیند کامل نشده است، قطع نمی‌شود، بنابراین اگر سعی کنید کاری انجام دهید که ممکن است زمان زیادی ببرد، احتیاط کنید.

+
+
+
+ + \ No newline at end of file diff --git a/external/book/content/book/fa/v2/Customizing-Git-Summary.html b/external/book/content/book/fa/v2/Customizing-Git-Summary.html index 91daaea0f6..0a1e1e7424 100644 --- a/external/book/content/book/fa/v2/Customizing-Git-Summary.html +++ b/external/book/content/book/fa/v2/Customizing-Git-Summary.html @@ -17,10 +17,14 @@ next: book/fa/v2/Git-and-Other-Systems-Git-as-a-Client title: Git - Summary --- -

Summary

-
-

We’ve covered most of the major ways that you can customize your Git client and server to best fit your workflow and projects. -You’ve learned about all sorts of configuration settings, file-based attributes, and event hooks, and you’ve built an example policy-enforcing server. -You should now be able to make Git fit nearly any workflow you can dream up.

-
- \ No newline at end of file +
+

خلاصه

+
+

ما بیشتر روش‌های اصلی که می‌توانید کلاینت و سرور گیت خود را برای بهترین تناسب با جریان کار و پروژه‌های خود سفارشی + کنید، پوشش داده‌ایم. + شما درباره انواع تنظیمات پیکربندی، ویژگی‌های مبتنی بر فایل و هوک‌های رویداد یاد گرفته‌اید و یک سرور نمونه که + سیاست‌ها را تحمیل می‌کند، ساخته‌اید. + اکنون باید بتوانید گیت را به گونه‌ای تنظیم کنید که تقریباً با هر جریانی که تصور می‌کنید، سازگار باشد.

+
+ +
\ No newline at end of file diff --git a/external/book/content/book/fa/v2/Git-Internals-Environment-Variables.html b/external/book/content/book/fa/v2/Git-Internals-Environment-Variables.html index 18cf82d575..4a5cf84906 100644 --- a/external/book/content/book/fa/v2/Git-Internals-Environment-Variables.html +++ b/external/book/content/book/fa/v2/Git-Internals-Environment-Variables.html @@ -17,217 +17,256 @@ next: book/fa/v2/Git-Internals-Summary title: Git - Environment Variables --- -

Environment Variables

-
-

Git always runs inside a bash shell, and uses a number of shell environment variables to determine how it behaves. -Occasionally, it comes in handy to know what these are, and how they can be used to make Git behave the way you want it to. -This isn’t an exhaustive list of all the environment variables Git pays attention to, but we’ll cover the most useful.

-
-
-

Global Behavior

-
-

Some of Git’s general behavior as a computer program depends on environment variables.

-
-
-

GIT_EXEC_PATH determines where Git looks for its sub-programs (like git-commit, git-diff, and others). - You can check the current setting by running git --exec-path.

-
-
-

HOME isn’t usually considered customizable (too many other things depend on it), but it’s where Git looks for the global configuration file. - If you want a truly portable Git installation, complete with global configuration, you can override HOME in the portable Git’s shell profile.

-
-
-

PREFIX is similar, but for the system-wide configuration. - Git looks for this file at $PREFIX/etc/gitconfig.

-
-
-

GIT_CONFIG_NOSYSTEM, if set, disables the use of the system-wide configuration file. - This is useful if your system config is interfering with your commands, but you don’t have access to change or remove it.

-
-
-

GIT_PAGER controls the program used to display multi-page output on the command line. -If this is unset, PAGER will be used as a fallback.

-
-
-

GIT_EDITOR is the editor Git will launch when the user needs to edit some text (a commit message, for example). -If unset, EDITOR will be used.

-
-
-
-

Repository Locations

-
-

Git uses several environment variables to determine how it interfaces with the current repository.

-
-
-

GIT_DIR is the location of the .git folder. -If this isn’t specified, Git walks up the directory tree until it gets to ~ or /, looking for a .git directory at every step.

-
-
-

GIT_CEILING_DIRECTORIES controls the behavior of searching for a .git directory. -If you access directories that are slow to load (such as those on a tape drive, or across a slow network connection), you may want to have Git stop trying earlier than it might otherwise, especially if Git is invoked when building your shell prompt.

-
-
-

GIT_WORK_TREE is the location of the root of the working directory for a non-bare repository. -If --git-dir or GIT_DIR is specified but none of --work-tree, GIT_WORK_TREE or core.worktree is specified, the current working directory is regarded as the top level of your working tree.

-
-
-

GIT_INDEX_FILE is the path to the index file (non-bare repositories only).

-
-
-

GIT_OBJECT_DIRECTORY can be used to specify the location of the directory that usually resides at .git/objects.

-
-
-

GIT_ALTERNATE_OBJECT_DIRECTORIES is a colon-separated list (formatted like /dir/one:/dir/two:…) which tells Git where to check for objects if they aren’t in GIT_OBJECT_DIRECTORY. -If you happen to have a lot of projects with large files that have the exact same contents, this can be used to avoid storing too many copies of them.

-
-
-
-

Pathspecs

-
-

A “pathspec” refers to how you specify paths to things in Git, including the use of wildcards. -These are used in the .gitignore file, but also on the command-line (git add *.c).

-
-
-

GIT_GLOB_PATHSPECS and GIT_NOGLOB_PATHSPECS control the default behavior of wildcards in pathspecs. -If GIT_GLOB_PATHSPECS is set to 1, wildcard characters act as wildcards (which is the default); if GIT_NOGLOB_PATHSPECS is set to 1, wildcard characters only match themselves, meaning something like *.c would only match a file named “*.c”, rather than any file whose name ends with .c. -You can override this in individual cases by starting the pathspec with :(glob) or :(literal), as in :(glob)*.c.

-
-
-

GIT_LITERAL_PATHSPECS disables both of the above behaviors; no wildcard characters will work, and the override prefixes are disabled as well.

-
-
-

GIT_ICASE_PATHSPECS sets all pathspecs to work in a case-insensitive manner.

-
-
-
-

Committing

-
-

The final creation of a Git commit object is usually done by git-commit-tree, which uses these environment variables as its primary source of information, falling back to configuration values only if these aren’t present.

-
-
-

GIT_AUTHOR_NAME is the human-readable name in the “author” field.

-
-
-

GIT_AUTHOR_EMAIL is the email for the “author” field.

-
-
-

GIT_AUTHOR_DATE is the timestamp used for the “author” field.

-
-
-

GIT_COMMITTER_NAME sets the human name for the “committer” field.

-
-
-

GIT_COMMITTER_EMAIL is the email address for the “committer” field.

-
-
-

GIT_COMMITTER_DATE is used for the timestamp in the “committer” field.

-
-
-

EMAIL is the fallback email address in case the user.email configuration value isn’t set. -If this isn’t set, Git falls back to the system user and host names.

-
-
-
-

Networking

-
-

Git uses the curl library to do network operations over HTTP, so GIT_CURL_VERBOSE tells Git to emit all the messages generated by that library. -This is similar to doing curl -v on the command line.

-
-
-

GIT_SSL_NO_VERIFY tells Git not to verify SSL certificates. -This can sometimes be necessary if you’re using a self-signed certificate to serve Git repositories over HTTPS, or you’re in the middle of setting up a Git server but haven’t installed a full certificate yet.

-
-
-

If the data rate of an HTTP operation is lower than GIT_HTTP_LOW_SPEED_LIMIT bytes per second for longer than GIT_HTTP_LOW_SPEED_TIME seconds, Git will abort that operation. -These values override the http.lowSpeedLimit and http.lowSpeedTime configuration values.

-
-
-

GIT_HTTP_USER_AGENT sets the user-agent string used by Git when communicating over HTTP. -The default is a value like git/2.0.0.

-
-
-
-

Diffing and Merging

-
-

GIT_DIFF_OPTS is a bit of a misnomer. -The only valid values are -u<n> or --unified=<n>, which controls the number of context lines shown in a git diff command.

-
-
-

GIT_EXTERNAL_DIFF is used as an override for the diff.external configuration value. -If it’s set, Git will invoke this program when git diff is invoked.

-
-
-

GIT_DIFF_PATH_COUNTER and GIT_DIFF_PATH_TOTAL are useful from inside the program specified by GIT_EXTERNAL_DIFF or diff.external. -The former represents which file in a series is being diffed (starting with 1), and the latter is the total number of files in the batch.

-
-
-

GIT_MERGE_VERBOSITY controls the output for the recursive merge strategy. -The allowed values are as follows:

-
-
-
    -
  • -

    0 outputs nothing, except possibly a single error message.

    -
  • -
  • -

    1 shows only conflicts.

    -
  • -
  • -

    2 also shows file changes.

    -
  • -
  • -

    3 shows when files are skipped because they haven’t changed.

    -
  • -
  • -

    4 shows all paths as they are processed.

    -
  • -
  • -

    5 and above show detailed debugging information.

    -
  • -
-
-
-

The default value is 2.

-
-
-
-

Debugging

-
-

Want to really know what Git is up to? -Git has a fairly complete set of traces embedded, and all you need to do is turn them on. -The possible values of these variables are as follows:

-
-
-
    -
  • -

    “true”, “1”, or “2” – the trace category is written to stderr.

    -
  • -
  • -

    An absolute path starting with / – the trace output will be written to that file.

    -
  • -
-
-
-

GIT_TRACE controls general traces, which don’t fit into any specific category. -This includes the expansion of aliases, and delegation to other sub-programs.

-
-
-
+
+

متغیرهای محیطی

+
+

گیت همیشه درون یک bash شل اجرا می‌شود و از تعدادی متغیر محیطی شل برای تعیین رفتار خود استفاده + می‌کند. + گاهی اوقات دانستن این متغیرها و نحوه استفاده از آن‌ها برای تنظیم رفتار گیت به شکلی که می‌خواهید، مفید است. + این لیست شامل تمام متغیرهای محیطی نیست که گیت به آن‌ها توجه می‌کند، اما ما به مهم‌ترین آن‌ها خواهیم پرداخت.

+
+
+

رفتار جهانی

+
+

برخی از رفتارهای عمومی گیت به عنوان یک برنامه کامپیوتری به متغیرهای محیطی بستگی دارد.

+
+
+

GIT_EXEC_PATH تعیین می‌کند که گیت به دنبال زیر برنامه‌های خود (مانند git-commit، + git-diff و دیگران) در کجا باشد. + می‌توانید با اجرای git --exec-path تنظیمات فعلی را بررسی کنید.

+
+
+

HOME معمولاً به عنوان یک متغیر قابل تنظیم در نظر گرفته نمی‌شود (زیرا به چیزهای + زیادی وابسته است)، اما جایی است که گیت به دنبال فایل پیکربندی جهانی می‌گردد. + اگر می‌خواهید یک نصب گیت واقعاً قابل حمل داشته باشید، همراه با پیکربندی جهانی، می‌توانید HOME را در + پروفایل شل گیت قابل حمل خود بازنویسی کنید.

+
+
+

PREFIX مشابه HOME است، اما برای پیکربندی سراسری سیستم. + گیت به دنبال این فایل در $PREFIX/etc/gitconfig می‌گردد.

+
+
+

GIT_CONFIG_NOSYSTEM، اگر تنظیم شده باشد، استفاده از فایل پیکربندی سراسری سیستم را + غیرفعال می‌کند. + این برای زمانی مفید است که پیکربندی سیستم شما با دستورات شما تداخل دارد، اما شما به تغییر یا حذف آن دسترسی + ندارید.

+
+
+

GIT_PAGER برنامه‌ای را که برای نمایش خروجی چند صفحه‌ای در خط فرمان استفاده + می‌شود، کنترل می‌کند. + اگر این تنظیم نشده باشد، PAGER به عنوان یک گزینه پشتیبان استفاده خواهد شد.

+
+
+

GIT_EDITOR ویرایشگری است که گیت هنگام نیاز کاربر به ویرایش متن (به عنوان مثال، + پیام کامیت) راه‌اندازی می‌کند. + اگر تنظیم نشده باشد، EDITOR استفاده خواهد شد.

+
+
+
+

مکان‌های مخزن

+
+

گیت از چندین متغیر محیطی برای تعیین نحوه تعامل با مخزن فعلی استفاده می‌کند.

+
+
+

GIT_DIR مکان پوشه .git است. + اگر این مشخص نشده باشد، گیت به سمت بالا در درخت دایرکتوری حرکت می‌کند تا به ~ یا / + برسد و در هر مرحله به دنبال دایرکتوری .git می‌گردد.

+
+
+

GIT_CEILING_DIRECTORIES رفتار جستجو برای دایرکتوری .git را کنترل + می‌کند. + اگر به دایرکتوری‌هایی دسترسی پیدا کنید که بارگذاری آن‌ها کند است (مانند دایرکتوری‌های روی درایو نوار یا از طریق + یک اتصال شبکه کند)، ممکن است بخواهید گیت زودتر از آنچه که ممکن است، تلاش را متوقف کند، به ویژه اگر گیت در هنگام + ساختن پرامپت شل شما فراخوانی شود.

+
+
+

GIT_WORK_TREE مکان ریشه دایرکتوری کاری برای یک مخزن غیر خالی است. + اگر --git-dir یا GIT_DIR مشخص شده باشد اما هیچ یک از --work-tree، GIT_WORK_TREE + یا core.worktree مشخص نشده باشد، دایرکتوری کاری فعلی به عنوان بالاترین سطح درخت کاری شما در نظر + گرفته می‌شود.

+
+
+

GIT_INDEX_FILE مسیر فایل ایندکس (فقط برای مخازن غیر خالی) است.

+
+
+

GIT_OBJECT_DIRECTORY می‌تواند برای مشخص کردن مکان دایرکتوری که معمولاً در .git/objects + قرار دارد، استفاده شود.

+
+
+

GIT_ALTERNATE_OBJECT_DIRECTORIES یک لیست جدا شده با دو نقطه (به شکل /dir/one:/dir/two:…) + است که به گیت می‌گوید کجا به دنبال اشیاء بگردد اگر آن‌ها در GIT_OBJECT_DIRECTORY نباشند. + اگر شما پروژه‌های زیادی با فایل‌های بزرگ که محتوای یکسانی دارند، داشته باشید، می‌توانید از این برای جلوگیری از + ذخیره‌سازی بیش از حد نسخه‌های آن‌ها استفاده کنید.

+
+
+
+

مسیرها

+
+

یک "pathspec" به نحوه مشخص کردن مسیرها در گیت اشاره دارد، از جمله استفاده از کاراکترهای wildcard. + این‌ها در فایل .gitignore استفاده می‌شوند، اما همچنین در خط فرمان (git add *.c) نیز + کاربرد دارند.

+
+
+

GIT_GLOB_PATHSPECS و GIT_NOGLOB_PATHSPECS رفتار + پیش‌فرض کاراکترهای wildcard در pathspecs را کنترل می‌کنند. + اگر GIT_GLOB_PATHSPECS به 1 تنظیم شود، کاراکترهای wildcard به عنوان wildcard عمل می‌کنند (که این + پیش‌فرض است)؛ اگر GIT_NOGLOB_PATHSPECS به 1 تنظیم شود، کاراکترهای wildcard فقط خودشان را مطابقت + می‌دهند، به این معنی که چیزی مانند *.c فقط با فایلی که نامش " *.c" است، مطابقت خواهد داشت، + نه هر فایلی که نامش با .c پایان می‌یابد. + شما می‌توانید این را در موارد فردی با شروع pathspec با :(glob) یا :(literal) بازنویسی + کنید، مانند :(glob)*.c.

+
+
+

GIT_LITERAL_PATHSPECS هر دو رفتار فوق را غیرفعال می‌کند؛ هیچ کاراکتر wildcardی + کار نخواهد کرد و پیشوندهای بازنویسی نیز غیرفعال خواهند شد.

+
+
+

GIT_ICASE_PATHSPECS تمام pathspecها را به صورت غیر حساس به حروف بزرگ و کوچک تنظیم + می‌کند.

+
+
+
+

کامیت کردن

+
+

ایجاد نهایی یک شیء کامیت گیت معمولاً توسط git-commit-tree انجام می‌شود که از این متغیرهای محیطی به + عنوان منبع اصلی اطلاعات خود استفاده می‌کند و تنها در صورت عدم وجود آن‌ها به مقادیر پیکربندی بازمی‌گردد.

+
+
+

GIT_AUTHOR_NAME نام قابل خواندن انسانی در فیلد "نویسنده" است.

+
+
+

GIT_AUTHOR_EMAIL ایمیل برای فیلد "نویسنده" است.

+
+
+

GIT_AUTHOR_DATE زمان‌سنجی استفاده شده برای فیلد "نویسنده" است.

+
+
+

GIT_COMMITTER_NAME نام انسانی برای فیلد "کامیت‌کننده" را تنظیم می‌کند.

+
+
+

GIT_COMMITTER_EMAIL آدرس ایمیل برای فیلد "کامیت‌کننده" است.

+
+
+

GIT_COMMITTER_DATE برای زمان‌سنجی در فیلد "کامیت‌کننده" استفاده می‌شود.

+
+
+

EMAIL آدرس ایمیل پشتیبان است در صورتی که مقدار پیکربندی user.email + تنظیم نشده باشد. + اگر این تنظیم نشده باشد، گیت به نام‌های کاربری و میزبان سیستم بازمی‌گردد.

+
+
+
+

شبکه

+
+

گیت از کتابخانه curl برای انجام عملیات شبکه‌ای بر روی HTTP استفاده می‌کند، بنابراین GIT_CURL_VERBOSE + به گیت می‌گوید که تمام پیام‌های تولید شده توسط آن کتابخانه را نمایش دهد. + این مشابه اجرای curl -v در خط فرمان است.

+
+
+

GIT_SSL_NO_VERIFY به گیت می‌گوید که گواهی‌های SSL را تأیید نکند. + این ممکن است گاهی لازم باشد اگر شما از یک گواهی خود امضا شده برای ارائه مخازن گیت از طریق HTTPS استفاده می‌کنید، + یا در حال راه‌اندازی یک سرور گیت هستید اما هنوز گواهی کامل را نصب نکرده‌اید.

+
+
+

اگر نرخ داده یک عملیات HTTP کمتر از GIT_HTTP_LOW_SPEED_LIMIT بایت در ثانیه برای + مدت زمان بیشتر از GIT_HTTP_LOW_SPEED_TIME ثانیه باشد، گیت آن عملیات را متوقف خواهد + کرد. + این مقادیر مقادیر پیکربندی http.lowSpeedLimit و http.lowSpeedTime را بازنویسی می‌کنند. +

+
+
+

GIT_HTTP_USER_AGENT رشته user-agent را که گیت هنگام ارتباط بر روی HTTP استفاده + می‌کند، تنظیم می‌کند. + پیش‌فرض یک مقدار مانند git/2.0.0 است.

+
+
+
+

تفاوت و ادغام

+
+

GIT_DIFF_OPTS کمی نامناسب است. + تنها مقادیر معتبر -u<n> یا --unified=<n> هستند که تعداد خطوط زمینه‌ای را + که در یک دستور git diff نمایش داده می‌شود، کنترل می‌کند.

+
+
+

GIT_EXTERNAL_DIFF به عنوان یک بازنویسی برای مقدار پیکربندی + diff.external استفاده می‌شود. + اگر تنظیم شده باشد، گیت این برنامه را هنگام فراخوانی git diff فراخوانی خواهد کرد.

+
+
+

GIT_DIFF_PATH_COUNTER و GIT_DIFF_PATH_TOTAL از داخل + برنامه‌ای که توسط GIT_EXTERNAL_DIFF یا diff.external مشخص شده، مفید هستند. + اولی نمایانگر این است که کدام فایل در یک سری در حال تفاوت است (از 1 شروع می‌شود) و دومی تعداد کل فایل‌ها در دسته + است.

+
+
+

GIT_MERGE_VERBOSITY خروجی استراتژی ادغام بازگشتی را کنترل می‌کند. + مقادیر مجاز به شرح زیر است:

+
+
+
    +
  • +

    0 هیچ چیزی را خروجی نمی‌دهد، به جز ممکن است یک پیام خطا.

    +
  • +
  • +

    1 فقط تضادها را نشان می‌دهد.

    +
  • +
  • +

    2 همچنین تغییرات فایل را نشان می‌دهد.

    +
  • +
  • +

    3 نشان می‌دهد که فایل‌ها به دلیل عدم تغییر نادیده گرفته شده‌اند.

    +
  • +
  • +

    4 تمام مسیرها را در حین پردازش نشان می‌دهد.

    +
  • +
  • +

    5 و بالاتر اطلاعات اشکال‌زدایی دقیق را نشان می‌دهد.

    +
  • +
+
+
+

مقدار پیش‌فرض 2 است.

+
+
+
+

اشکال‌زدایی

+
+

می‌خواهید واقعاً بدانید گیت چه کار می‌کند؟ + گیت مجموعه‌ای نسبتاً کامل از ردیابی‌ها را در خود دارد و تنها کاری که باید انجام دهید این است که آن‌ها را فعال + کنید. + مقادیر ممکن این متغیرها به شرح زیر است:

+
+
+
    +
  • +

    “true”، “1”، یا “2” – دسته ردیابی به stderr نوشته می‌شود.

    +
  • +
  • +

    یک مسیر مطلق که با / شروع می‌شود – خروجی ردیابی به آن فایل نوشته می‌شود.

    +
  • +
+
+
+

GIT_TRACE ردیابی‌های عمومی را کنترل می‌کند که در هیچ دسته خاصی قرار نمی‌گیرند. + این شامل گسترش مستعارها و واگذاری به سایر زیر برنامه‌ها است.

+
+
+
$ GIT_TRACE=true git lga
 20:12:49.877982 git.c:554               trace: exec: 'git-lga'
 20:12:49.878369 run-command.c:341       trace: run_command: 'git-lga'
 20:12:49.879529 git.c:282               trace: alias expansion: lga => 'log' '--graph' '--pretty=oneline' '--abbrev-commit' '--decorate' '--all'
-20:12:49.879885 git.c:349               trace: built-in: git 'log' '--graph' '--pretty=oneline' '--abbrev-commit' '--decorate' '--all'
+20:12:49.879885 run-command.c:349       trace: built-in: git 'log' '--graph' '--pretty=oneline' '--abbrev-commit' '--decorate' '--all'
 20:12:49.899217 run-command.c:341       trace: run_command: 'less'
 20:12:49.899675 run-command.c:192       trace: exec: 'less'
-
-
-
-

GIT_TRACE_PACK_ACCESS controls tracing of packfile access. -The first field is the packfile being accessed, the second is the offset within that file:

-
-
-
+
+
+
+

GIT_TRACE_PACK_ACCESS ردیابی دسترسی به فایل‌های pack را کنترل می‌کند. + اولین فیلد فایل pack در حال دسترسی است، دومی آفست درون آن فایل:

+
+
+
$ GIT_TRACE_PACK_ACCESS=true git status
 20:10:12.081397 sha1_file.c:2088        .git/objects/pack/pack-c3fa...291e.pack 12
 20:10:12.081886 sha1_file.c:2088        .git/objects/pack/pack-c3fa...291e.pack 34662
@@ -238,13 +277,13 @@ 

Debugging

On branch master Your branch is up-to-date with 'origin/master'. nothing to commit, working directory clean
-
-
-
-

GIT_TRACE_PACKET enables packet-level tracing for network operations.

-
-
-
+
+
+
+

GIT_TRACE_PACKET ردیابی سطح بسته برای عملیات شبکه را فعال می‌کند.

+
+
+
$ GIT_TRACE_PACKET=true git ls-remote origin
 20:15:14.867043 pkt-line.c:46           packet:          git< # service=git-upload-pack
 20:15:14.867071 pkt-line.c:46           packet:          git< 0000
@@ -252,14 +291,14 @@ 

Debugging

20:15:14.867088 pkt-line.c:46 packet: git< 0f20ae29889d61f2e93ae00fd34f1cdb53285702 refs/heads/ab/add-interactive-show-diff-func-name 20:15:14.867094 pkt-line.c:46 packet: git< 36dc827bc9d17f80ed4f326de21247a5d1341fbc refs/heads/ah/doc-gitk-config # […]
-
-
-
-

GIT_TRACE_PERFORMANCE controls logging of performance data. -The output shows how long each particular git invocation takes.

-
-
-
+
+
+
+

GIT_TRACE_PERFORMANCE کنترل ثبت داده‌های عملکرد را بر عهده دارد. + خروجی نشان می‌دهد که هر فراخوانی خاص git چقدر طول می‌کشد.

+
+
+
$ GIT_TRACE_PERFORMANCE=true git gc
 20:18:19.499676 trace.c:414             performance: 0.374835000 s: git command: 'git' 'pack-refs' '--all' '--prune'
 20:18:19.845585 trace.c:414             performance: 0.343020000 s: git command: 'git' 'reflog' 'expire' '--all'
@@ -276,13 +315,14 @@ 

Debugging

20:18:25.225424 trace.c:414 performance: 1.616423000 s: git command: 'git' 'prune' '--expire' '2.weeks.ago' 20:18:25.232403 trace.c:414 performance: 0.001051000 s: git command: 'git' 'rerere' 'gc' 20:18:25.233159 trace.c:414 performance: 6.112217000 s: git command: 'git' 'gc'
-
-
-
-

GIT_TRACE_SETUP shows information about what Git is discovering about the repository and environment it’s interacting with.

-
-
-
+
+
+
+

GIT_TRACE_SETUP اطلاعاتی درباره آنچه گیت در حال کشف در مورد مخزن و محیطی که با آن + تعامل دارد، نشان می‌دهد.

+
+
+
$ GIT_TRACE_SETUP=true git status
 20:19:47.086765 trace.c:315             setup: git_dir: .git
 20:19:47.087184 trace.c:316             setup: worktree: /Users/ben/src/git
@@ -291,42 +331,53 @@ 

Debugging

On branch master Your branch is up-to-date with 'origin/master'. nothing to commit, working directory clean
-
-
-
-
-

Miscellaneous

-
-

GIT_SSH, if specified, is a program that is invoked instead of ssh when Git tries to connect to an SSH host. -It is invoked like $GIT_SSH [username@]host [-p <port>] <command>. -Note that this isn’t the easiest way to customize how ssh is invoked; it won’t support extra command-line parameters, so you’d have to write a wrapper script and set GIT_SSH to point to it. -It’s probably easier just to use the ~/.ssh/config file for that.

-
-
-

GIT_ASKPASS is an override for the core.askpass configuration value. -This is the program invoked whenever Git needs to ask the user for credentials, which can expect a text prompt as a command-line argument, and should return the answer on stdout. -(See }}">Credential Storage for more on this subsystem.)

-
-
-

GIT_NAMESPACE controls access to namespaced refs, and is equivalent to the --namespace flag. -This is mostly useful on the server side, where you may want to store multiple forks of a single repository in one repository, only keeping the refs separate.

-
-
-

GIT_FLUSH can be used to force Git to use non-buffered I/O when writing incrementally to stdout. -A value of 1 causes Git to flush more often, a value of 0 causes all output to be buffered. -The default value (if this variable is not set) is to choose an appropriate buffering scheme depending on the activity and the output mode.

-
-
-

GIT_REFLOG_ACTION lets you specify the descriptive text written to the reflog. -Here’s an example:

-
-
-
-
$ GIT_REFLOG_ACTION="my action" git commit --allow-empty -m 'My message'
-[master 9e3d55a] My message
+      
+
+
+
+

متفرقه

+
+

GIT_SSH، اگر مشخص شده باشد، برنامه‌ای است که به جای ssh هنگام تلاش + گیت برای اتصال به یک میزبان SSH فراخوانی می‌شود. + این به شکل $GIT_SSH [username@]host [-p <port>] <command> فراخوانی می‌شود. + توجه داشته باشید که این آسان‌ترین راه برای سفارشی کردن نحوه فراخوانی ssh نیست؛ این از پارامترهای + اضافی خط فرمان پشتیبانی نمی‌کند، بنابراین شما باید یک اسکریپت wrapper بنویسید و GIT_SSH را به آن + اشاره کنید. + احتمالاً بهتر است فقط از فایل ~/.ssh/config برای این کار استفاده کنید.

+
+
+

GIT_ASKPASS یک بازنویسی برای مقدار پیکربندی core.askpass است. + این برنامه‌ای است که هر بار که گیت نیاز به درخواست اعتبارنامه از کاربر دارد، فراخوانی می‌شود و می‌تواند انتظار + یک متن درخواست به عنوان آرگومان خط فرمان را داشته باشد و باید پاسخ را در stdout برگرداند. + (برای اطلاعات بیشتر در مورد این زیرسیستم، به + }}">Credential Storage + مراجعه کنید.)

+
+
+

GIT_NAMESPACE دسترسی به refs نام‌گذاری شده را کنترل می‌کند و معادل با پرچم --namespace + است. + این بیشتر در سمت سرور مفید است، جایی که ممکن است بخواهید چندین فورک از یک مخزن واحد را در یک مخزن ذخیره کنید و + فقط refs را جدا نگه دارید.

+
+
+

GIT_FLUSH می‌تواند برای مجبور کردن گیت به استفاده از I/O غیر بافر شده هنگام نوشتن + به تدریج به stdout استفاده شود. + مقدار 1 باعث می‌شود گیت بیشتر flush کند، و مقدار 0 باعث می‌شود تمام خروجی بافر شود. + مقدار پیش‌فرض (اگر این متغیر تنظیم نشده باشد) انتخاب یک طرح بافر مناسب بسته به فعالیت و حالت خروجی است.

+
+
+

GIT_REFLOG_ACTION به شما اجازه می‌دهد متن توصیفی نوشته شده به reflog را مشخص + کنید. + در اینجا یک مثال است:

+
+
+
+
$ GIT_REFLOG_ACTION="عمل من" git commit --allow-empty -m 'پیام من'
+[master 9e3d55a] پیام من
 $ git reflog -1
-9e3d55a HEAD@{0}: my action: My message
-
-
-
- \ No newline at end of file +9e3d55a HEAD@{0}: عمل من: پیام من
+
+
+
+ +
\ No newline at end of file diff --git a/external/book/content/book/fa/v2/Git-and-Other-Systems-Migrating-to-Git.html b/external/book/content/book/fa/v2/Git-and-Other-Systems-Migrating-to-Git.html index d72bf8e2a5..4cc2ba07f3 100644 --- a/external/book/content/book/fa/v2/Git-and-Other-Systems-Migrating-to-Git.html +++ b/external/book/content/book/fa/v2/Git-and-Other-Systems-Migrating-to-Git.html @@ -17,275 +17,312 @@ next: book/fa/v2/Git-and-Other-Systems-Summary title: Git - Migrating to Git --- -

Migrating to Git

-
-

-If you have an existing codebase in another VCS but you’ve decided to start using Git, you must migrate your project one way or another. -This section goes over some importers for common systems, and then demonstrates how to develop your own custom importer. -You’ll learn how to import data from several of the bigger professionally used SCM systems, because they make up the majority of users who are switching, and because high-quality tools for them are easy to come by.

-
-
-

Subversion

-
-

- -If you read the previous section about using git svn, you can easily use those instructions to git svn clone a repository; then, stop using the Subversion server, push to a new Git server, and start using that. -If you want the history, you can accomplish that as quickly as you can pull the data out of the Subversion server (which may take a while).

-
-
-

However, the import isn’t perfect; and because it will take so long, you may as well do it right. -The first problem is the author information. -In Subversion, each person committing has a user on the system who is recorded in the commit information. -The examples in the previous section show schacon in some places, such as the blame output and the git svn log. -If you want to map this to better Git author data, you need a mapping from the Subversion users to the Git authors. -Create a file called users.txt that has this mapping in a format like this:

-
-
-
+
+

مهاجرت به گیت

+
+

+ اگر شما یک کدبیس موجود در یک VCS دیگر دارید اما تصمیم به استفاده از گیت گرفته‌اید، باید پروژه خود را به هر نحوی + مهاجرت کنید. + این بخش به بررسی برخی از واردکننده‌ها برای سیستم‌های رایج می‌پردازد و سپس نشان می‌دهد که چگونه می‌توانید یک + واردکننده سفارشی خود را توسعه دهید. + شما یاد خواهید گرفت که چگونه داده‌ها را از چندین سیستم SCM حرفه‌ای بزرگ وارد کنید، زیرا آن‌ها بخش عمده‌ای از + کاربرانی هستند که در حال تغییر هستند و ابزارهای با کیفیت برای آن‌ها به راحتی در دسترس است.

+
+
+

ساب‌ورژن

+
+

+ + اگر بخش قبلی را درباره استفاده از git svn خوانده‌اید، می‌توانید به راحتی از آن دستورالعمل‌ها برای + git svn clone یک مخزن استفاده کنید؛ سپس، استفاده از سرور ساب‌ورژن را متوقف کرده، به یک سرور گیت + جدید فشار دهید و شروع به استفاده از آن کنید. + اگر می‌خواهید تاریخچه را داشته باشید، می‌توانید این کار را به سرعت انجام دهید، همانطور که می‌توانید داده‌ها را + از سرور ساب‌ورژن خارج کنید (که ممکن است مدتی طول بکشد).

+
+
+

با این حال، واردات کامل نیست؛ و از آنجا که این کار زمان زیادی می‌برد، بهتر است آن را به درستی انجام دهید. + اولین مشکل اطلاعات نویسنده است. + در ساب‌ورژن، هر شخصی که کامیت می‌کند، یک کاربر در سیستم دارد که در اطلاعات کامیت ثبت می‌شود. + مثال‌های بخش قبلی نشان می‌دهند که schacon در برخی مکان‌ها، مانند خروجی blame و git + svn log وجود دارد. + اگر می‌خواهید این را به داده‌های نویسنده بهتری در گیت نگاشت کنید، به یک نگاشت از کاربران ساب‌ورژن به نویسندگان + گیت نیاز دارید. + یک فایل به نام users.txt ایجاد کنید که این نگاشت را به فرمت زیر داشته باشد:

+
+
+
schacon = Scott Chacon <schacon@geemail.com>
 selse = Someo Nelse <selse@geemail.com>
-
-
-
-

To get a list of the author names that SVN uses, you can run this:

-
-
-
+
+
+
+

برای دریافت لیستی از نام‌های نویسنده‌ای که SVN استفاده می‌کند، می‌توانید این دستور را اجرا کنید:

+
+
+
$ svn log --xml --quiet | grep author | sort -u | \
   perl -pe 's/.*>(.*?)<.*/$1 = /'
-
-
-
-

That generates the log output in XML format, then keeps only the lines with author information, discards duplicates, strips out the XML tags. -Obviously this only works on a machine with grep, sort, and perl installed. -Then, redirect that output into your users.txt file so you can add the equivalent Git user data next to each entry.

-
-
- - - - - -
-
یادداشت
-
-
-

If you’re trying this on a Windows machine, this is the point where you’ll run into trouble. -Microsoft have provided some good advice and samples at https://docs.microsoft.com/en-us/azure/devops/repos/git/perform-migration-from-svn-to-git.

-
-
-
-
-

You can provide this file to git svn to help it map the author data more accurately. -You can also tell git svn not to include the metadata that Subversion normally imports, by passing --no-metadata to the clone or init command. -The metadata includes a git-svn-id inside each commit message that Git will generate during import. -This can bloat your Git log and might make it a bit unclear.

-
-
- - - - - -
-
یادداشت
-
-
-

You need to keep the metadata when you want to mirror commits made in the Git repository back into the original SVN repository. -If you don’t want the synchronization in your commit log, feel free to omit the --no-metadata parameter.

-
-
-
-
-

This makes your import command look like this:

-
-
-
+
+
+
+

این خروجی لاگ را به فرمت XML تولید می‌کند، سپس فقط خطوطی که اطلاعات نویسنده را دارند نگه می‌دارد، تکراری‌ها را + حذف می‌کند و تگ‌های XML را حذف می‌کند. + بدیهی است که این فقط بر روی سیستمی که grep، sort و perl نصب شده کار + می‌کند. + سپس، آن خروجی را به فایل users.txt خود هدایت کنید تا بتوانید داده‌های معادل کاربر گیت را در کنار هر + ورودی اضافه کنید.

+
+
+ + + + + +
+
یادداشت
+
+
+

اگر این کار را بر روی یک ماشین ویندوزی انجام می‌دهید، اینجا جایی است که با مشکل مواجه خواهید شد. + مایکروسافت برخی نکات و نمونه‌های خوب را در https://docs.microsoft.com/en-us/azure/devops/repos/git/perform-migration-from-svn-to-git + ارائه داده است.

+
+
+
+
+

شما می‌توانید این فایل را به git svn ارائه دهید تا به آن کمک کند داده‌های نویسنده را به طور + دقیق‌تری نگاشت کند. + همچنین می‌توانید به git svn بگویید که متاداده‌ای که ساب‌ورژن معمولاً وارد می‌کند را شامل نشود، با + عبور از --no-metadata به دستور clone یا init. + متاداده شامل یک git-svn-id در هر پیام کامیت است که گیت در حین واردات تولید می‌کند. + این می‌تواند لاگ گیت شما را بزرگ کند و ممکن است کمی نامشخص باشد.

+
+
+ + + + + +
+
یادداشت
+
+
+

شما باید متاداده را نگه دارید زمانی که می‌خواهید کامیت‌های انجام شده در مخزن گیت را به مخزن اصلی + ساب‌ورژن برگردانید. + اگر نمی‌خواهید همگام‌سازی در لاگ کامیت شما باشد، می‌توانید پارامتر --no-metadata را حذف + کنید.

+
+
+
+
+

این دستور import شما را به شکل زیر می‌کند:

+
+
+
$ git svn clone http://my-project.googlecode.com/svn/ \
       --authors-file=users.txt --no-metadata --prefix "" -s my_project
 $ cd my_project
-
-
-
-

Now you should have a nicer Subversion import in your my_project directory. -Instead of commits that look like this

-
-
-
+
+
+
+

اکنون باید یک واردات ساب‌ورژن زیباتر در دایرکتوری my_project خود داشته باشید. + به جای کامیت‌هایی که به این شکل به نظر می‌رسند

+
+
+
commit 37efa680e8473b615de980fa935944215428a35a
-Author: schacon <schacon@4c93b258-373f-11de-be05-5f7a86268029>
+Author: schacon <schacon@>
 Date:   Sun May 3 00:12:22 2009 +0000
 
     fixed install - go to trunk
 
     git-svn-id: https://my-project.googlecode.com/svn/trunk@94 4c93b258-373f-11de-
     be05-5f7a86268029
-
-
-
-

they look like this:

-
-
-
+
+
+
+

آن‌ها به این شکل به نظر می‌رسند:

+
+
+
commit 03a8785f44c8ea5cdb0e8834b7c8e6c469be2ff2
 Author: Scott Chacon <schacon@geemail.com>
 Date:   Sun May 3 00:12:22 2009 +0000
 
     fixed install - go to trunk
-
-
-
-

Not only does the Author field look a lot better, but the git-svn-id is no longer there, either.

-
-
-

You should also do a bit of post-import cleanup. -For one thing, you should clean up the weird references that git svn set up. -First you’ll move the tags so they’re actual tags rather than strange remote branches, and then you’ll move the rest of the branches so they’re local.

-
-
-

To move the tags to be proper Git tags, run:

-
-
-
-
$ for t in $(git for-each-ref --format='%(refname:short)' refs/remotes/tags); do git tag ${t/tags\//} $t && git branch -D -r $t; done
-
-
-
-

This takes the references that were remote branches that started with refs/remotes/tags/ and makes them real (lightweight) tags.

-
-
-

Next, move the rest of the references under refs/remotes to be local branches:

-
-
-
-
$ for b in $(git for-each-ref --format='%(refname:short)' refs/remotes); do git branch $b refs/remotes/$b && git branch -D -r $b; done
-
-
-
-

It may happen that you’ll see some extra branches which are suffixed by @xxx (where xxx is a number), while in Subversion you only see one branch. -This is actually a Subversion feature called “peg-revisions”, which is something that Git simply has no syntactical counterpart for. -Hence, git svn simply adds the svn version number to the branch name just in the same way as you would have written it in svn to address the peg-revision of that branch. -If you do not care anymore about the peg-revisions, simply remove them:

-
-
-
-
$ for p in $(git for-each-ref --format='%(refname:short)' | grep @); do git branch -D $p; done
-
-
-
-

Now all the old branches are real Git branches and all the old tags are real Git tags.

-
-
-

There’s one last thing to clean up. -Unfortunately, git svn creates an extra branch named trunk, which maps to Subversion’s default branch, but the trunk ref points to the same place as master. -Since master is more idiomatically Git, here’s how to remove the extra branch:

-
-
-
-
$ git branch -d trunk
-
-
-
-

The last thing to do is add your new Git server as a remote and push to it. -Here is an example of adding your server as a remote:

-
-
-
-
$ git remote add origin git@my-git-server:myrepository.git
-
-
-
-

Because you want all your branches and tags to go up, you can now run this:

-
-
-
+
+
+
+

نه تنها فیلد نویسنده به مراتب بهتر به نظر می‌رسد، بلکه git-svn-id نیز دیگر وجود ندارد.

+
+
+

شما همچنین باید کمی تمیزکاری پس از واردات انجام دهید. + برای یک چیز، باید ارجاعات عجیبی که git svn تنظیم کرده است را پاک کنید. + اول، برچسب‌ها را به گونه‌ای منتقل کنید که برچسب‌های واقعی باشند نه شاخه‌های دور از نوع عجیب، و سپس بقیه شاخه‌ها + را به شاخه‌های محلی منتقل کنید.

+
+
+

برای انتقال برچسب‌ها به برچسب‌های واقعی گیت، این دستور را اجرا کنید:

+
+
+
+
$ for t in $(git for-each-ref --format='%(refname:short)' refs/remotes/tags); do git tag ${t/tags\//} $t && git branch -D -r $t; done
+
+
+
+

این ارجاعات را که شاخه‌های دور بودند و با refs/remotes/tags/ شروع می‌شدند، به برچسب‌های واقعی + (سبک) تبدیل می‌کند.

+
+
+

سپس، بقیه ارجاعات زیر refs/remotes را به شاخه‌های محلی منتقل کنید:

+
+
+
+
$ for b in $(git for-each-ref --format='%(refname:short)' refs/remotes); do git branch $b refs/remotes/$b && git branch -D -r $b; done
+
+
+
+

ممکن است ببینید که برخی از شاخه‌های اضافی وجود دارند که با @xxx (که xxx یک عدد است) ختم می‌شوند، + در حالی که در ساب‌ورژن فقط یک شاخه می‌بینید. + این واقعاً یک ویژگی ساب‌ورژن به نام "peg-revisions" است که چیزی است که گیت به سادگی معادل نحوی ندارد. + بنابراین، git svn به سادگی شماره نسخه svn را به نام شاخه اضافه می‌کند، درست به همان روشی که شما در + svn می‌نویسید تا به peg-revision آن شاخه اشاره کنید. + اگر دیگر به peg-revisions اهمیتی نمی‌دهید، به سادگی آن‌ها را حذف کنید:

+
+
+
+
$ for p in $(git for-each-ref --format='%(refname:short)' | grep @); do git branch -D $p; done
+
+
+
+

اکنون تمام شاخه‌های قدیمی، شاخه‌های واقعی گیت هستند و تمام برچسب‌های قدیمی، برچسب‌های واقعی گیت هستند.

+
+
+

یک چیز آخر برای تمیز کردن وجود دارد. + متأسفانه، git svn یک شاخه اضافی به نام trunk ایجاد می‌کند که به شاخه پیش‌فرض ساب‌ورژن + اشاره دارد، اما ارجاع trunk به همان مکان master اشاره می‌کند. + از آنجا که master به طور ایدئولوژیک گیت است، اینجا چگونگی حذف شاخه اضافی است:

+
+
+
+
$ git branch -d trunk
+
+
+
+

آخرین کاری که باید انجام دهید این است که سرور گیت جدید خود را به عنوان یک ریموت اضافه کنید و به آن فشار دهید. + در اینجا یک مثال از افزودن سرور خود به عنوان یک ریموت است:

+
+
+
+
$ git remote add origin git@my-git-server:myrepository.git
+
+
+
+

زیرا می‌خواهید تمام شاخه‌ها و برچسب‌های خود را بالا ببرید، اکنون می‌توانید این را اجرا کنید:

+
+
+
$ git push origin --all
 $ git push origin --tags
-
-
-
-

All your branches and tags should be on your new Git server in a nice, clean import.

-
-
-
-

Mercurial

-
-

-Since Mercurial and Git have fairly similar models for representing versions, and since Git is a bit more flexible, converting a repository from Mercurial to Git is fairly straightforward, using a tool called "hg-fast-export", which you’ll need a copy of:

-
-
-
-
$ git clone https://github.com/frej/fast-export.git
-
-
-
-

The first step in the conversion is to get a full clone of the Mercurial repository you want to convert:

-
-
-
-
$ hg clone <remote repo URL> /tmp/hg-repo
-
-
-
-

The next step is to create an author mapping file. -Mercurial is a bit more forgiving than Git for what it will put in the author field for changesets, so this is a good time to clean house. -Generating this is a one-line command in a bash shell:

-
-
-
+
+
+
+

تمام شاخه‌ها و برچسب‌های شما باید در سرور گیت جدید شما در یک واردات زیبا و تمیز باشد.

+
+
+
+

مرکیوریال

+
+

+ از آنجا که مرکیوریال و گیت مدل‌های نسبتاً مشابهی برای نمایش نسخه‌ها دارند و از آنجا که گیت کمی انعطاف‌پذیرتر + است، تبدیل یک مخزن از مرکیوریال به گیت نسبتاً ساده است، با استفاده از ابزاری به نام "hg-fast-export" که شما به + یک نسخه از آن نیاز دارید:

+
+
+
+
$ git clone https://github.com/frej/fast-export.git
+
+
+
+

اولین مرحله در تبدیل، دریافت یک کلون کامل از مخزن مرکیوریال است که می‌خواهید تبدیل کنید:

+
+
+
+
$ hg clone <remote repo URL> /tmp/hg-repo
+
+
+
+

مرحله بعدی ایجاد یک فایل نگاشت نویسنده است. + مرکیوریال کمی بیشتر از گیت در مورد آنچه که در فیلد نویسنده برای تغییرات قرار می‌دهد، بخشنده است، بنابراین این + زمان خوبی برای تمیز کردن است. + تولید این یک دستور یک‌خطی در یک شل bash است:

+
+
+
$ cd /tmp/hg-repo
 $ hg log | grep user: | sort | uniq | sed 's/user: *//' > ../authors
-
-
-
-

This will take a few seconds, depending on how long your project’s history is, and afterwards the /tmp/authors file will look something like this:

-
-
-
+
+
+
+

این چند ثانیه طول می‌کشد، بسته به اینکه تاریخچه پروژه شما چقدر طولانی است، و بعد از آن فایل + /tmp/authors به شکل زیر خواهد بود:

+
+
+
bob
 bob@localhost
 bob <bob@company.com>
 bob jones <bob <AT> company <DOT> com>
 Bob Jones <bob@company.com>
 Joe Smith <joe@company.com>
-
-
-
-

In this example, the same person (Bob) has created changesets under four different names, one of which actually looks correct, and one of which would be completely invalid for a Git commit. -Hg-fast-export lets us fix this by turning each line into a rule: "<input>"="<output>", mapping an <input> to an <output>. -Inside the <input> and <output> strings, all escape sequences understood by the python string_escape encoding are supported. -If the author mapping file does not contain a matching <input>, that author will be sent on to Git unmodified. -If all the usernames look fine, we won’t need this file at all. -In this example, we want our file to look like this:

-
-
-
+
+
+
+

در این مثال، همان شخص (باب) تغییرات را تحت چهار نام مختلف ایجاد کرده است، یکی از آن‌ها واقعاً درست به نظر + می‌رسد و یکی از آن‌ها کاملاً نامعتبر برای یک کامیت گیت خواهد بود. + Hg-fast-export به ما اجازه می‌دهد این را با تبدیل هر خط به یک قانون اصلاح کنیم: "<input>"="<output>"، + که یک <input> را به یک <output> نگاشت می‌کند. + در داخل رشته‌های <input> و <output>، تمام توالی‌های فرار که توسط کدگذاری + string_escape پایتون درک می‌شوند، پشتیبانی می‌شوند. + اگر فایل نگاشت نویسنده شامل یک <input> مطابقت نداشته باشد، آن نویسنده بدون تغییر به گیت ارسال + می‌شود. + اگر تمام نام‌های کاربری خوب به نظر برسند، ما به این فایل نیازی نخواهیم داشت. + در این مثال، ما می‌خواهیم فایل ما به این شکل باشد:

+
+
+
"bob"="Bob Jones <bob@company.com>"
 "bob@localhost"="Bob Jones <bob@company.com>"
 "bob <bob@company.com>"="Bob Jones <bob@company.com>"
 "bob jones <bob <AT> company <DOT> com>"="Bob Jones <bob@company.com>"
-
-
-
-

The same kind of mapping file can be used to rename branches and tags when the Mercurial name is not allowed by Git.

-
-
-

The next step is to create our new Git repository, and run the export script:

-
-
-
+
+
+
+

همین نوع فایل نگاشت می‌تواند برای تغییر نام شاخه‌ها و برچسب‌ها زمانی که نام مرکیوریال توسط گیت مجاز نیست، + استفاده شود.

+
+
+

مرحله بعدی ایجاد مخزن جدید گیت ما و اجرای اسکریپت صادرات است:

+
+
+
$ git init /tmp/converted
 $ cd /tmp/converted
 $ /tmp/fast-export/hg-fast-export.sh -r /tmp/hg-repo -A /tmp/authors
-
-
-
-

The -r flag tells hg-fast-export where to find the Mercurial repository we want to convert, and the -A flag tells it where to find the author-mapping file (branch and tag mapping files are specified by the -B and -T flags respectively). -The script parses Mercurial changesets and converts them into a script for Git’s "fast-import" feature (which we’ll discuss in detail a bit later on). -This takes a bit (though it’s much faster than it would be over the network), and the output is fairly verbose:

-
-
-
+
+
+
+

پرچم -r به hg-fast-export می‌گوید که کجا مخزن مرکیوریال که می‌خواهیم تبدیل کنیم را پیدا کند و پرچم + -A به آن می‌گوید که کجا فایل نگاشت نویسنده را پیدا کند (فایل‌های نگاشت شاخه و برچسب به ترتیب با + پرچم‌های -B و -T مشخص می‌شوند). + این اسکریپت تغییرات مرکیوریال را تجزیه می‌کند و آن‌ها را به یک اسکریپت برای ویژگی "fast-import" گیت تبدیل می‌کند + (که در ادامه به تفصیل در مورد آن صحبت خواهیم کرد). + این کمی طول می‌کشد (اگرچه این بسیار سریع‌تر از آن است که از طریق شبکه باشد)، و خروجی نسبتاً verbose + است:

+
+
+
$ /tmp/fast-export/hg-fast-export.sh -r /tmp/hg-repo -A /tmp/authors
 Loaded 4 authors
 master: Exporting full revision 1/22208 with 13/0/0 added/changed/removed files
@@ -328,276 +365,303 @@ 

Mercurial

$ git shortlog -sn 369 Bob Jones 365 Joe Smith
-
-
-
-

That’s pretty much all there is to it. -All of the Mercurial tags have been converted to Git tags, and Mercurial branches and bookmarks have been converted to Git branches. -Now you’re ready to push the repository up to its new server-side home:

-
-
-
+
+
+
+

این تقریباً تمام چیزی است که باید انجام دهید. + تمام برچسب‌های مرکیوریال به برچسب‌های گیت تبدیل شده‌اند و شاخه‌ها و نشانک‌های مرکیوریال به شاخه‌های گیت تبدیل + شده‌اند. + اکنون شما آماده‌اید که مخزن را به سرور جدید خود فشار دهید:

+
+
+
$ git remote add origin git@my-git-server:myrepository.git
 $ git push origin --all
-
-
-
-
-

Bazaar

-
-

-
-
-

Bazaar is a DVCS tool much like Git, and as a result it’s pretty straightforward to convert a Bazaar repository into a Git one. -To accomplish this, you’ll need to import the bzr-fastimport plugin.

-
-
-

Getting the bzr-fastimport plugin

-
-

The procedure for installing the fastimport plugin is different on UNIX-like operating systems and on Windows. -In the first case, the simplest is to install the bzr-fastimport package that will install all the required dependencies.

-
-
-

For example, with Debian and derived, you would do the following:

-
-
-
-
$ sudo apt-get install bzr-fastimport
-
-
-
-

With RHEL, you would do the following:

-
-
-
-
$ sudo yum install bzr-fastimport
-
-
-
-

With Fedora, since release 22, the new package manager is dnf:

-
-
-
-
$ sudo dnf install bzr-fastimport
-
-
-
-

If the package is not available, you may install it as a plugin:

-
-
-
-
$ mkdir --parents ~/.bazaar/plugins     # creates the necessary folders for the plugins
+      
+
+
+
+

بازار

+
+

+
+
+

بازار یک ابزار DVCS است که بسیار شبیه به گیت است و به همین دلیل تبدیل یک مخزن بازار به گیت نسبتاً ساده است. + برای انجام این کار، شما به وارد کردن پلاگین bzr-fastimport نیاز دارید.

+
+
+

دریافت پلاگین bzr-fastimport

+
+

روش نصب پلاگین fastimport در سیستم‌عامل‌های شبیه UNIX و ویندوز متفاوت است. + در حالت اول، ساده‌ترین راه نصب بسته bzr-fastimport است که تمام وابستگی‌های لازم را نصب می‌کند. +

+
+
+

برای مثال، با دبیان و مشتقات آن، شما باید به صورت زیر عمل کنید:

+
+
+
+
$ sudo apt-get install bzr-fastimport
+
+
+
+

با RHEL، شما باید به صورت زیر عمل کنید:

+
+
+
+
$ sudo yum install bzr-fastimport
+
+
+
+

با فدورا، از آنجا که از نسخه 22 به بعد، مدیر بسته جدید dnf است:

+
+
+
+
$ sudo dnf install bzr-fastimport
+
+
+
+

اگر بسته در دسترس نیست، می‌توانید آن را به عنوان یک پلاگین نصب کنید:

+
+
+
+
$ mkdir --parents ~/.bazaar/plugins     # ایجاد پوشه‌های لازم برای پلاگین‌ها
 $ cd ~/.bazaar/plugins
-$ bzr branch lp:bzr-fastimport fastimport   # imports the fastimport plugin
+$ bzr branch lp:bzr-fastimport fastimport   # وارد کردن پلاگین fastimport
 $ cd fastimport
-$ sudo python setup.py install --record=files.txt   # installs the plugin
-
-
-
-

For this plugin to work, you’ll also need the fastimport Python module. -You can check whether it is present or not and install it with the following commands:

-
-
-
+$ sudo python setup.py install --record=files.txt # نصب پلاگین +
+
+
+

برای اینکه این پلاگین کار کند، شما همچنین به ماژول پایتون fastimport نیاز دارید. + می‌توانید بررسی کنید که آیا موجود است یا نه و با دستورات زیر آن را نصب کنید:

+
+
+
$ python -c "import fastimport"
 Traceback (most recent call last):
   File "<string>", line 1, in <module>
 ImportError: No module named fastimport
 $ pip install fastimport
-
-
-
-

If it is not available, you can download it at address https://pypi.python.org/pypi/fastimport/.

-
-
-

In the second case (on Windows), bzr-fastimport is automatically installed with the standalone version and the default installation (let all the checkboxes checked). -So in this case you have nothing to do.

-
-
-

At this point, the way to import a Bazaar repository differs according to that you have a single branch or you are working with a repository that has several branches.

-
-
-
-

Project with a single branch

-
-

Now cd in the directory that contains your Bazaar repository and initialize the Git repository:

-
-
-
+
+
+
+

اگر در دسترس نیست، می‌توانید آن را از آدرس https://pypi.python.org/pypi/fastimport/ + دانلود کنید.

+
+
+

در حالت دوم (در ویندوز)، bzr-fastimport به طور خودکار با نسخه مستقل و نصب پیش‌فرض (اجازه دهید + تمام جعبه‌های انتخاب شده باقی بمانند) نصب می‌شود. + بنابراین در این حالت شما هیچ کاری برای انجام ندارید.

+
+
+

در این مرحله، روش وارد کردن یک مخزن بازار بسته به اینکه آیا شما یک شاخه واحد دارید یا با مخزنی کار می‌کنید که + چندین شاخه دارد، متفاوت است.

+
+
+
+

پروژه با یک شاخه واحد

+
+

اکنون cd در دایرکتوری که مخزن بازار شما در آن قرار دارد و مخزن گیت را راه‌اندازی کنید:

+
+
+
$ cd /path/to/the/bzr/repository
 $ git init
-
-
-
-

Now, you can simply export your Bazaar repository and convert it into a Git repository using the following command:

-
-
-
-
$ bzr fast-export --plain . | git fast-import
-
-
-
-

Depending on the size of the project, your Git repository is built in a lapse from a few seconds to a few minutes.

-
-
-
-

Case of a project with a main branch and a working branch

-
-

You can also import a Bazaar repository that contains branches. -Let us suppose that you have two branches: one represents the main branch (myProject.trunk), the other one is the working branch (myProject.work).

-
-
-
+
+
+
+

اکنون، می‌توانید به سادگی مخزن بازار خود را صادر کرده و آن را به یک مخزن گیت تبدیل کنید با استفاده از دستور + زیر:

+
+
+
+
$ bzr fast-export --plain . | git fast-import
+
+
+
+

بسته به اندازه پروژه، مخزن گیت شما در یک بازه زمانی از چند ثانیه تا چند دقیقه ساخته می‌شود.

+
+
+
+

موردی از پروژه با یک شاخه اصلی و یک شاخه + کاری

+
+

شما همچنین می‌توانید یک مخزن بازار که شامل شاخه‌ها است را وارد کنید. + فرض کنید که شما دو شاخه دارید: یکی نمایانگر شاخه اصلی (myProject.trunk) و دیگری شاخه کاری (myProject.work) + است.

+
+
+
$ ls
 myProject.trunk myProject.work
-
-
-
-

Create the Git repository and cd into it:

-
-
-
+
+
+
+

مخزن گیت را ایجاد کنید و cd به آن بروید:

+
+
+
$ git init git-repo
 $ cd git-repo
-
-
-
-

Pull the master branch into git:

-
-
-
+
+
+
+

شاخه master را به گیت بکشید:

+
+
+
$ bzr fast-export --export-marks=../marks.bzr ../myProject.trunk | \
 git fast-import --export-marks=../marks.git
-
-
-
-

Pull the working branch into Git:

-
-
-
+
+
+
+

شاخه کاری را به گیت بکشید:

+
+
+
$ bzr fast-export --marks=../marks.bzr --git-branch=work ../myProject.work | \
 git fast-import --import-marks=../marks.git --export-marks=../marks.git
-
-
-
-

Now git branch shows you the master branch as well as the work branch. -Check the logs to make sure they’re complete and get rid of the marks.bzr and marks.git files.

-
-
-
-

Synchronizing the staging area

-
-

Whatever the number of branches you had and the import method you used, your staging area is not synchronized with HEAD, and with the import of several branches, your working directory is not synchronized either. -This situation is easily solved by the following command:

-
-
-
-
$ git reset --hard HEAD
-
-
-
-
-

Ignoring the files that were ignored with .bzrignore

-
-

Now let’s have a look at the files to ignore. -The first thing to do is to rename .bzrignore into .gitignore. -If the .bzrignore file contains one or several lines starting with "!!" or "RE:", you’ll have to modify it and perhaps create several .gitignore files in order to ignore exactly the same files that Bazaar was ignoring.

-
-
-

Finally, you will have to create a commit that contains this modification for the migration:

-
-
-
+
+
+
+

اکنون git branch به شما شاخه master و همچنین شاخه work را نشان می‌دهد. + لاگ‌ها را بررسی کنید تا مطمئن شوید که کامل هستند و فایل‌های marks.bzr و marks.git را + حذف کنید.

+
+
+
+

همگام‌سازی ناحیه موقت

+
+

هر تعداد شاخه‌ای که داشتید و روش وارداتی که استفاده کردید، ناحیه موقت شما با HEAD همگام نیست و + با واردات چندین شاخه، دایرکتوری کاری شما نیز همگام نیست. + این وضعیت به راحتی با دستور زیر حل می‌شود:

+
+
+
+
$ git reset --hard HEAD
+
+
+
+
+

نادیده گرفتن فایل‌هایی که با .bzrignore نادیده گرفته + شده‌اند

+
+

اکنون بیایید نگاهی به فایل‌هایی که باید نادیده گرفته شوند بیندازیم. + اولین کار این است که .bzrignore را به .gitignore تغییر نام دهید. + اگر فایل .bzrignore شامل یک یا چند خط باشد که با "!!" یا "RE:" شروع می‌شود، باید آن را اصلاح کنید + و شاید چندین .gitignore ایجاد کنید تا دقیقاً همان فایل‌هایی را که بازار نادیده می‌گرفت، نادیده + بگیرید.

+
+
+

در نهایت، شما باید یک کامیت ایجاد کنید که این اصلاح را برای مهاجرت شامل شود:

+
+
+
$ git mv .bzrignore .gitignore
-$ # modify .gitignore if needed
-$ git commit -am 'Migration from Bazaar to Git'
-
-
-
-
-

Sending your repository to the server

-
-

Here we are! -Now you can push the repository onto its new home server:

-
-
-
+$ # در صورت نیاز .gitignore را اصلاح کنید +$ git commit -am 'مهاجرت از بازار به گیت' +
+
+
+
+

ارسال مخزن شما به سرور

+
+

اینجا هستیم! + اکنون می‌توانید مخزن را به سرور جدید خود فشار دهید:

+
+
+
$ git remote add origin git@my-git-server:mygitrepository.git
 $ git push origin --all
 $ git push origin --tags
-
-
-
-

Your Git repository is ready to use.

-
-
-
-
-

Perforce

-
-

-The next system you’ll look at importing from is Perforce. -As we discussed above, there are two ways to let Git and Perforce talk to each other: git-p4 and Perforce Git Fusion.

-
-
-

Perforce Git Fusion

-
-

Git Fusion makes this process fairly painless. -Just configure your project settings, user mappings, and branches using a configuration file (as discussed in }}">Git Fusion), and clone the repository. -Git Fusion leaves you with what looks like a native Git repository, which is then ready to push to a native Git host if you desire. -You could even use Perforce as your Git host if you like.

-
-
-
-

Git-p4

-
-

Git-p4 can also act as an import tool. -As an example, we’ll import the Jam project from the Perforce Public Depot. -To set up your client, you must export the P4PORT environment variable to point to the Perforce depot:

-
-
-
-
$ export P4PORT=public.perforce.com:1666
-
-
-
- - - - - -
-
یادداشت
-
-
-

In order to follow along, you’ll need a Perforce depot to connect with. -We’ll be using the public depot at public.perforce.com for our examples, but you can use any depot you have access to.

-
-
-
-
-

-Run the git p4 clone command to import the Jam project from the Perforce server, supplying the depot and project path and the path into which you want to import the project:

-
-
-
+
+
+
+

مخزن گیت شما آماده استفاده است.

+
+
+
+
+

پر فورس

+
+

+ سیستم بعدی که به آن نگاه خواهید کرد وارد کردن از پر فورس است. + همانطور که در بالا بحث کردیم، دو راه برای ارتباط گیت و پر فورس وجود دارد: git-p4 و Perforce Git Fusion.

+
+
+

Perforce Git Fusion

+
+

گیت فیوژن این فرآیند را نسبتاً بدون دردسر می‌کند. + فقط تنظیمات پروژه، نگاشت‌های کاربر و شاخه‌ها را با استفاده از یک فایل پیکربندی تنظیم کنید (همانطور که در + }}">Git Fusion + ) + بحث شد)، و مخزن را کلون کنید. + گیت فیوژن به شما چیزی می‌دهد که به نظر می‌رسد یک مخزن گیت بومی است، که سپس آماده است تا به یک میزبان گیت بومی + فشار داده شود اگر بخواهید. + شما حتی می‌توانید از پر فورس به عنوان میزبان گیت خود استفاده کنید اگر بخواهید.

+
+
+
+

گیت-p4

+
+

گیت-p4 همچنین می‌تواند به عنوان یک ابزار واردات عمل کند. + به عنوان مثال، ما پروژه Jam را از مخزن عمومی پر فورس وارد خواهیم کرد. + برای تنظیم مشتری خود، باید متغیر محیط P4PORT را برای اشاره به مخزن پر فورس صادر کنید:

+
+
+
+
$ export P4PORT=public.perforce.com:1666
+
+
+
+ + + + + +
+
یادداشت
+
+
+

برای پیروی از این روند، شما به یک مخزن پر فورس نیاز دارید که به آن متصل شوید. + ما از مخزن عمومی در public.perforce.com برای مثال‌های خود استفاده خواهیم کرد، اما می‌توانید از هر + مخزنی که به آن دسترسی دارید استفاده کنید.

+
+
+
+
+

+ دستور git p4 clone را برای وارد کردن پروژه Jam از سرور پر فورس اجرا کنید، با ارائه مسیر مخزن و + پروژه و مسیری که می‌خواهید پروژه را در آن وارد کنید:

+
+
+
$ git-p4 clone //guest/perforce_software/jam@all p4import
 Importing from //guest/perforce_software/jam@all into p4import
 Initialized empty Git repository in /private/tmp/p4import/.git/
 Import destination: refs/remotes/p4/master
 Importing revision 9957 (100%)
-
-
-
-

This particular project has only one branch, but if you have branches that are configured with branch views (or just a set of directories), you can use the --detect-branches flag to git p4 clone to import all the project’s branches as well. -See }}">Branching for a bit more detail on this.

-
-
-

At this point you’re almost done. -If you go to the p4import directory and run git log, you can see your imported work:

-
-
-
+
+
+
+

این پروژه خاص فقط یک شاخه دارد، اما اگر شما شاخه‌هایی دارید که با نمای شاخه پیکربندی شده‌اند (یا فقط یک + مجموعه از دایرکتوری‌ها)، می‌توانید از پرچم --detect-branches برای git p4 clone + استفاده کنید تا تمام شاخه‌های پروژه را نیز وارد کنید. + برای جزئیات بیشتر به + }}">Branching + مراجعه کنید. +

+
+
+

در این مرحله تقریباً کارتان تمام است. + اگر به دایرکتوری p4import بروید و git log را اجرا کنید، می‌توانید کار وارد شده خود + را ببینید:

+
+
+
$ git log -2
 commit e5da1c909e5db3036475419f6379f2c73710c4e6
 Author: giles <giles@giles@perforce.com>
@@ -614,27 +678,29 @@ 

Git-p4

Fix spelling error on Jam doc page (cummulative -> cumulative). [git-p4: depot-paths = "//public/jam/src/": change = 7304]
-
-
-
-

You can see that git-p4 has left an identifier in each commit message. -It’s fine to keep that identifier there, in case you need to reference the Perforce change number later. -However, if you’d like to remove the identifier, now is the time to do so – before you start doing work on the new repository. - -You can use git filter-branch to remove the identifier strings en masse:

-
-
-
+
+
+
+

شما می‌توانید ببینید که git-p4 یک شناسه در هر پیام کامیت باقی گذاشته است. + نگه داشتن آن شناسه خوب است، در صورتی که بخواهید بعداً شماره تغییر پر فورس را ارجاع دهید. + با این حال، اگر می‌خواهید شناسه را حذف کنید، اکنون زمان آن است که این کار را انجام دهید – قبل از اینکه شروع به + کار بر روی مخزن جدید کنید. + + شما می‌توانید از git filter-branch برای حذف رشته‌های شناسه به صورت انبوه استفاده کنید:

+
+
+
$ git filter-branch --msg-filter 'sed -e "/^\[git-p4:/d"'
 Rewrite e5da1c909e5db3036475419f6379f2c73710c4e6 (125/125)
 Ref 'refs/heads/master' was rewritten
-
-
-
-

If you run git log, you can see that all the SHA-1 checksums for the commits have changed, but the git-p4 strings are no longer in the commit messages:

-
-
-
+
+
+
+

اگر git log را اجرا کنید، می‌توانید ببینید که تمام checksum‌های SHA-1 برای کامیت‌ها تغییر + کرده‌اند، اما رشته‌های git-p4 دیگر در پیام‌های کامیت وجود ندارند:

+
+
+
$ git log -2
 commit b17341801ed838d97f7800a54a6f9b95750839b7
 Author: giles <giles@giles@perforce.com>
@@ -647,168 +713,200 @@ 

Git-p4

Date: Tue Jul 7 01:35:51 2009 -0800 Fix spelling error on Jam doc page (cummulative -> cumulative).
-
-
-
-

Your import is ready to push up to your new Git server.

-
-
-
-
-

TFS

-
-

-If your team is converting their source control from TFVC to Git, you’ll want the highest-fidelity conversion you can get. -This means that, while we covered both git-tfs and git-tf for the interop section, we’ll only be covering git-tfs for this part, because git-tfs supports branches, and this is prohibitively difficult using git-tf.

-
-
- - - - - -
-
یادداشت
-
-
-

This is a one-way conversion. -The resulting Git repository won’t be able to connect with the original TFVC project.

-
-
-
-
-

The first thing to do is map usernames. -TFVC is fairly liberal with what goes into the author field for changesets, but Git wants a human-readable name and email address. -You can get this information from the tf command-line client, like so:

-
-
-
-
PS> tf history $/myproject -recursive > AUTHORS_TMP
-
-
-
-

This grabs all of the changesets in the history of the project and put it in the AUTHORS_TMP file that we will process to extract the data of the User column (the 2nd one). -Open the file and find at which characters start and end the column and replace, in the following command-line, the parameters 11-20 of the cut command with the ones found:

-
-
-
-
PS> cat AUTHORS_TMP | cut -b 11-20 | tail -n+3 | sort | uniq > AUTHORS
-
-
-
-

The cut command keeps only the characters between 11 and 20 from each line. -The tail command skips the first two lines, which are field headers and ASCII-art underlines. -The result of all of this is piped to sort and uniq to eliminate duplicates, and saved to a file named AUTHORS. -The next step is manual; in order for git-tfs to make effective use of this file, each line must be in this format:

-
-
-
-
DOMAIN\username = User Name <email@address.com>
-
-
-
-

The portion on the left is the “User” field from TFVC, and the portion on the right side of the equals sign is the user name that will be used for Git commits.

-
-
-

Once you have this file, the next thing to do is make a full clone of the TFVC project you’re interested in:

-
-
-
-
PS> git tfs clone --with-branches --authors=AUTHORS https://username.visualstudio.com/DefaultCollection $/project/Trunk project_git
-
-
-
-

Next you’ll want to clean the git-tfs-id sections from the bottom of the commit messages. -The following command will do that:

-
-
-
-
PS> git filter-branch -f --msg-filter 'sed "s/^git-tfs-id:.*$//g"' '--' --all
-
-
-
-

That uses the sed command from the Git-bash environment to replace any line starting with “git-tfs-id:” with emptiness, which Git will then ignore.

-
-
-

Once that’s all done, you’re ready to add a new remote, push all your branches up, and have your team start working from Git.

-
-
-
-

A Custom Importer

-
-

- -If your system isn’t one of the above, you should look for an importer online – quality importers are available for many other systems, including CVS, Clear Case, Visual Source Safe, even a directory of archives. -If none of these tools works for you, you have a more obscure tool, or you otherwise need a more custom importing process, you should use git fast-import. -This command reads simple instructions from stdin to write specific Git data. -It’s much easier to create Git objects this way than to run the raw Git commands or try to write the raw objects (see }}">Git Internals for more information). -This way, you can write an import script that reads the necessary information out of the system you’re importing from and prints straightforward instructions to stdout. -You can then run this program and pipe its output through git fast-import.

-
-
-

To quickly demonstrate, you’ll write a simple importer. -Suppose you work in current, you back up your project by occasionally copying the directory into a time-stamped back_YYYY_MM_DD backup directory, and you want to import this into Git. -Your directory structure looks like this:

-
-
-
+
+
+
+

واردات شما آماده است تا به سرور گیت جدید خود فشار داده شود.

+
+
+
+
+

TFS

+
+

+ اگر تیم شما در حال تبدیل کنترل منبع خود از TFVC به گیت است، شما می‌خواهید بالاترین دقت ممکن را در تبدیل داشته + باشید. + این بدان معناست که، در حالی که ما هر دو git-tfs و git-tf را برای بخش تعامل پوشش داده‌ایم، ما فقط به git-tfs برای + این بخش خواهیم پرداخت، زیرا git-tfs از شاخه‌ها پشتیبانی می‌کند و این کار با استفاده از git-tf به شدت دشوار + است.

+
+
+ + + + + +
+
یادداشت
+
+
+

این یک تبدیل یک‌طرفه است. + مخزن گیت حاصل نمی‌تواند با پروژه اصلی TFVC متصل شود.

+
+
+
+
+

اولین کاری که باید انجام دهید نگاشت نام‌های کاربری است. + TFVC نسبت به آنچه که در فیلد نویسنده برای تغییرات قرار می‌دهد، نسبتاً آزاد است، اما گیت به یک نام و آدرس ایمیل + قابل خواندن برای انسان نیاز دارد. + شما می‌توانید این اطلاعات را از کلاینت خط فرمان tf به این صورت دریافت کنید:

+
+
+
+
PS> tf history $/myproject -recursive > AUTHORS_TMP
+
+
+
+

این تمام تغییرات در تاریخچه پروژه را می‌گیرد و در فایل AUTHORS_TMP قرار می‌دهد که ما آن را پردازش خواهیم کرد تا + داده‌های ستون User (دومین) را استخراج کنیم. + فایل را باز کنید و ببینید که کدام کاراکترها شروع و پایان ستون هستند و در دستور زیر، پارامترهای + 11-20 دستور cut را با آن‌ها جایگزین کنید:

+
+
+
+
PS> cat AUTHORS_TMP | cut -b 11-20 | tail -n+3 | sort | uniq > AUTHORS
+
+
+
+

دستور cut فقط کاراکترهای بین 11 و 20 را از هر خط نگه می‌دارد. + دستور tail دو خط اول را که سرصفحه‌های فیلد و زیرنویس‌های ASCII هستند، نادیده می‌گیرد. + نتیجه همه این‌ها به sort و uniq ارسال می‌شود تا تکراری‌ها حذف شوند و در فایلی به نام + AUTHORS ذخیره شود. + مرحله بعدی دستی است؛ برای اینکه git-tfs به طور مؤثر از این فایل استفاده کند، هر خط باید به این فرمت باشد:

+
+
+
+
DOMAIN\username = User Name <email@address.com>
+
+
+
+

بخش سمت چپ فیلد "User" از TFVC است و بخش سمت راست علامت مساوی نام کاربری است که برای کامیت‌های گیت استفاده + خواهد شد.

+
+
+

پس از اینکه این فایل را دارید، کار بعدی این است که یک کلون کامل از پروژه TFVC که به آن علاقه دارید، ایجاد + کنید:

+
+
+
+
PS> git tfs clone --with-branches --authors=AUTHORS https://username.visualstudio.com/DefaultCollection $/project/Trunk project_git
+
+
+
+

سپس می‌خواهید بخش‌های git-tfs-id را از انتهای پیام‌های کامیت پاک کنید. + دستور زیر این کار را انجام می‌دهد:

+
+
+
+
PS> git filter-branch -f --msg-filter 'sed "s/^git-tfs-id:.*$//g"' '--' --all
+
+
+
+

این از دستور sed در محیط Git-bash استفاده می‌کند تا هر خطی که با "git-tfs-id:" شروع می‌شود را با + خالی جایگزین کند، که گیت سپس آن را نادیده می‌گیرد.

+
+
+

پس از اینکه همه این کارها انجام شد، شما آماده‌اید که یک ریموت جدید اضافه کنید، تمام شاخه‌های خود را فشار دهید و + تیم خود را از گیت شروع به کار کنید.

+
+
+
+

یک واردکننده سفارشی

+
+

+ + اگر سیستم شما یکی از موارد بالا نیست، باید به دنبال یک واردکننده آنلاین باشید – واردکننده‌های با کیفیت برای + بسیاری از سیستم‌های دیگر، از جمله CVS، Clear Case، Visual Source Safe، حتی یک دایرکتوری از آرشیوها در دسترس + هستند. + اگر هیچ‌یک از این ابزارها برای شما کار نمی‌کند، شما یک ابزار کمتر شناخته شده دارید، یا به هر دلیلی به یک فرآیند + واردات سفارشی نیاز دارید، باید از git fast-import استفاده کنید. + این دستور از stdin دستورالعمل‌های ساده‌ای می‌خواند تا داده‌های خاص گیت را بنویسد. + این روش بسیار آسان‌تر است تا اینکه دستورات خام گیت را اجرا کنید یا سعی کنید اشیاء خام را بنویسید (برای اطلاعات + بیشتر به }}">Git Internals مراجعه کنید). + به این ترتیب، می‌توانید یک اسکریپت واردات بنویسید که اطلاعات لازم را از سیستمی که از آن وارد می‌کنید بخواند و + دستورالعمل‌های ساده‌ای را به stdout چاپ کند. + سپس می‌توانید این برنامه را اجرا کرده و خروجی آن را از طریق git fast-import هدایت کنید.

+
+
+

برای نشان دادن سریع، شما یک واردکننده ساده خواهید نوشت. + فرض کنید شما در current کار می‌کنید، پروژه خود را با کپی کردن دایرکتوری به طور دوره‌ای به یک + دایرکتوری پشتیبان با زمان‌مهر back_YYYY_MM_DD پشتیبان‌گیری می‌کنید و می‌خواهید این را به گیت وارد + کنید. + ساختار دایرکتوری شما به این شکل است:

+
+
+
$ ls /opt/import_from
 back_2014_01_02
 back_2014_01_04
 back_2014_01_14
 back_2014_02_03
 current
-
-
-
-

In order to import a Git directory, you need to review how Git stores its data. -As you may remember, Git is fundamentally a linked list of commit objects that point to a snapshot of content. -All you have to do is tell fast-import what the content snapshots are, what commit data points to them, and the order they go in. -Your strategy will be to go through the snapshots one at a time and create commits with the contents of each directory, linking each commit back to the previous one.

-
-
-

As we did in }}">An Example Git-Enforced Policy, we’ll write this in Ruby, because it’s what we generally work with and it tends to be easy to read. -You can write this example pretty easily in anything you’re familiar with – it just needs to print the appropriate information to stdout. -And, if you are running on Windows, this means you’ll need to take special care to not introduce carriage returns at the end your lines – git fast-import is very particular about just wanting line feeds (LF) not the carriage return line feeds (CRLF) that Windows uses.

-
-
-

To begin, you’ll change into the target directory and identify every subdirectory, each of which is a snapshot that you want to import as a commit. -You’ll change into each subdirectory and print the commands necessary to export it. -Your basic main loop looks like this:

-
-
-
+
+
+
+

برای وارد کردن یک دایرکتوری گیت، شما باید بررسی کنید که گیت چگونه داده‌های خود را ذخیره می‌کند. + همانطور که ممکن است به یاد داشته باشید، گیت اساساً یک لیست پیوندی از اشیاء کامیت است که به یک تصویر از محتوا + اشاره می‌کند. + تنها کاری که باید انجام دهید این است که به fast-import بگویید که محتوای تصاویر چیست، داده‌های کامیت + به آن‌ها اشاره می‌کند و ترتیب آن‌ها چگونه است. + استراتژی شما این خواهد بود که به صورت یک به یک از تصاویر عبور کنید و کامیت‌هایی با محتوای هر دایرکتوری ایجاد + کنید و هر کامیت را به کامیت قبلی پیوند دهید.

+
+
+

همانطور که در + }}">An Example Git-Enforced Policy + انجام دادیم، ما این را در Ruby خواهیم نوشت، زیرا این چیزی است که ما معمولاً با آن کار می‌کنیم و + معمولاً خواندن آن آسان است. + شما می‌توانید این مثال را به راحتی در هر چیزی که با آن آشنا هستید بنویسید – فقط باید اطلاعات مناسب را به stdout + چاپ کند. + و اگر شما در حال اجرای ویندوز هستید، این بدان معناست که باید مراقب باشید که در انتهای خطوط خود کاراکترهای بازگشت + کاراکتر را معرفی نکنید – git fast-import بسیار خاص است که فقط می‌خواهد خط‌های جدید (LF) و نه بازگشت + خط‌های کاراکتر (CRLF) که ویندوز استفاده می‌کند.

+
+
+

برای شروع، شما به دایرکتوری هدف تغییر می‌دهید و هر زیر دایرکتوری را شناسایی می‌کنید، که هر کدام یک تصویر است که + می‌خواهید به عنوان یک کامیت وارد کنید. + شما به هر زیر دایرکتوری تغییر می‌دهید و دستورات لازم برای صادرات آن را چاپ می‌کنید. + حلقه اصلی شما به این شکل به نظر می‌رسد:

+
+
+
last_mark = nil
 
-# loop through the directories
+# حلقه از طریق دایرکتوری‌ها
 Dir.chdir(ARGV[0]) do
   Dir.glob("*").each do |dir|
     next if File.file?(dir)
 
-    # move into the target directory
+    # به دایرکتوری هدف بروید
     Dir.chdir(dir) do
       last_mark = print_export(dir, last_mark)
     end
   end
 end
-
-
-
-

You run print_export inside each directory, which takes the manifest and mark of the previous snapshot and returns the manifest and mark of this one; that way, you can link them properly. -“Mark” is the fast-import term for an identifier you give to a commit; as you create commits, you give each one a mark that you can use to link to it from other commits. -So, the first thing to do in your print_export method is generate a mark from the directory name:

-
-
-
-
mark = convert_dir_to_mark(dir)
-
-
-
-

You’ll do this by creating an array of directories and using the index value as the mark, because a mark must be an integer. -Your method looks like this:

-
-
-
+
+
+
+

شما print_export را در هر دایرکتوری اجرا می‌کنید، که مانفیست و علامت تصویر قبلی را می‌گیرد و + مانفیست و علامت این تصویر را برمی‌گرداند؛ به این ترتیب، می‌توانید آن‌ها را به درستی پیوند دهید. + "علامت" اصطلاح fast-import برای یک شناسه است که به یک کامیت می‌دهید؛ وقتی کامیت‌ها را ایجاد + می‌کنید، به هر یک علامتی می‌دهید که می‌توانید از آن برای پیوند به آن از کامیت‌های دیگر استفاده کنید. + بنابراین، اولین کاری که باید در متد print_export خود انجام دهید این است که یک علامت از نام + دایرکتوری تولید کنید:

+
+
+
+
mark = convert_dir_to_mark(dir)
+
+
+
+

شما این کار را با ایجاد یک آرایه از دایرکتوری‌ها و استفاده از مقدار ایندکس به عنوان علامت انجام می‌دهید، زیرا + یک علامت باید یک عدد صحیح باشد. + متد شما به این شکل به نظر می‌رسد:

+
+
+
$marks = []
 def convert_dir_to_mark(dir)
   if !$marks.include?(dir)
@@ -816,23 +914,23 @@ 

A Custom Importer

end ($marks.index(dir) + 1).to_s end
-
-
-
-

Now that you have an integer representation of your commit, you need a date for the commit metadata. -Because the date is expressed in the name of the directory, you’ll parse it out. -The next line in your print_export file is:

-
-
-
-
date = convert_dir_to_date(dir)
-
-
-
-

where convert_dir_to_date is defined as:

-
-
-
+
+
+
+

اکنون که یک نمایندگی عددی از کامیت خود دارید، به یک تاریخ برای متاداده کامیت نیاز دارید. + زیرا تاریخ در نام دایرکتوری بیان شده است، شما آن را تجزیه می‌کنید. + خط بعدی در فایل print_export شما این است:

+
+
+
+
date = convert_dir_to_date(dir)
+
+
+
+

که convert_dir_to_date به این شکل تعریف شده است:

+
+
+
def convert_dir_to_date(dir)
   if dir == 'current'
     return Time.now().to_i
@@ -842,133 +940,145 @@ 

A Custom Importer

return Time.local(year, month, day).to_i end end
-
-
-
-

That returns an integer value for the date of each directory. -The last piece of meta-information you need for each commit is the committer data, which you hardcode in a global variable:

-
-
-
-
$author = 'John Doe <john@example.com>'
-
-
-
-

Now you’re ready to begin printing out the commit data for your importer. -The initial information states that you’re defining a commit object and what branch it’s on, followed by the mark you’ve generated, the committer information and commit message, and then the previous commit, if any. -The code looks like this:

-
-
-
-
# print the import information
+      
+
+
+

این یک مقدار عددی برای تاریخ هر دایرکتوری برمی‌گرداند. + آخرین قطعه اطلاعات متاداده‌ای که به هر کامیت نیاز دارید، داده‌های کامیت‌کننده است که شما در یک متغیر جهانی + سخت‌کد می‌کنید:

+
+
+
+
$author = 'John Doe <john@example.com>'
+
+
+
+

اکنون شما آماده‌اید که داده‌های کامیت را برای واردکننده خود چاپ کنید. + اطلاعات اولیه بیان می‌کند که شما یک شیء کامیت را تعریف می‌کنید و در کدام شاخه است، به دنبال علامتی که تولید + کرده‌اید، اطلاعات کامیت‌کننده و پیام کامیت، و سپس کامیت قبلی، در صورت وجود. + کد به این شکل به نظر می‌رسد:

+
+
+
+
# چاپ اطلاعات واردات
 puts 'commit refs/heads/master'
 puts 'mark :' + mark
 puts "committer #{$author} #{date} -0700"
 export_data('imported from ' + dir)
 puts 'from :' + last_mark if last_mark
-
-
-
-

You hardcode the time zone (-0700) because doing so is easy. -If you’re importing from another system, you must specify the time zone as an offset. -The commit message must be expressed in a special format:

-
-
-
-
data (size)\n(contents)
-
-
-
-

The format consists of the word data, the size of the data to be read, a newline, and finally the data. -Because you need to use the same format to specify the file contents later, you create a helper method, export_data:

-
-
-
+
+
+
+

شما زمان منطقه را سخت‌کد می‌کنید (-0700) زیرا انجام این کار آسان است. + اگر از سیستم دیگری وارد می‌کنید، باید زمان منطقه را به عنوان یک آفست مشخص کنید. + پیام کامیت باید به یک فرمت خاص بیان شود:

+
+
+
+
data (size)\n(contents)
+
+
+
+

فرمت شامل کلمه data، اندازه داده‌ای که باید خوانده شود، یک خط جدید و در نهایت داده است. + زیرا شما نیاز دارید از همان فرمت برای مشخص کردن محتوای فایل‌ها بعداً استفاده کنید، یک متد کمکی به نام export_data + ایجاد می‌کنید:

+
+
+
def export_data(string)
   print "data #{string.size}\n#{string}"
 end
-
-
-
-

All that’s left is to specify the file contents for each snapshot. -This is easy, because you have each one in a directory – you can print out the deleteall command followed by the contents of each file in the directory. -Git will then record each snapshot appropriately:

-
-
-
+
+
+
+

تنها چیزی که باقی مانده است مشخص کردن محتوای فایل‌ها برای هر تصویر است. + این کار آسان است، زیرا شما هر یک را در یک دایرکتوری دارید – می‌توانید دستور deleteall را چاپ کنید و + سپس محتوای هر فایل در دایرکتوری را چاپ کنید. + سپس گیت هر تصویر را به درستی ثبت می‌کند:

+
+
+
puts 'deleteall'
 Dir.glob("**/*").each do |file|
   next if !File.file?(file)
   inline_data(file)
 end
-
-
-
-

Note: Because many systems think of their revisions as changes from one commit to another, fast-import can also take commands with each commit to specify which files have been added, removed, or modified and what the new contents are. -You could calculate the differences between snapshots and provide only this data, but doing so is more complex – you may as well give Git all the data and let it figure it out. -If this is better suited to your data, check the fast-import man page for details about how to provide your data in this manner.

-
-
-

The format for listing the new file contents or specifying a modified file with the new contents is as follows:

-
-
-
+
+
+
+

توجه: از آنجا که بسیاری از سیستم‌ها تغییرات خود را به عنوان تغییرات از یک کامیت به کامیت دیگر می‌دانند، + fast-import همچنین می‌تواند دستورات را با هر کامیت بگیرد تا مشخص کند کدام فایل‌ها اضافه، حذف یا تغییر یافته‌اند + و محتوای جدید چیست. + شما می‌توانید تفاوت‌ها بین تصاویر را محاسبه کنید و فقط این داده‌ها را ارائه دهید، اما انجام این کار پیچیده‌تر + است – شما می‌توانید به سادگی به گیت تمام داده‌ها را بدهید و بگذارید خودش آن را حل کند. + اگر این برای داده‌های شما بهتر است، به صفحه man fast-import برای جزئیات در مورد نحوه ارائه داده‌های + خود به این روش مراجعه کنید.

+
+
+

فرمت برای فهرست کردن محتوای فایل‌های جدید یا مشخص کردن یک فایل تغییر یافته با محتوای جدید به شکل زیر است:

+
+
+
M 644 inline path/to/file
 data (size)
 (file contents)
-
-
-
-

Here, 644 is the mode (if you have executable files, you need to detect and specify 755 instead), and inline says you’ll list the contents immediately after this line. -Your inline_data method looks like this:

-
-
-
+
+
+
+

در اینجا، 644 حالت است (اگر فایل‌های اجرایی دارید، باید آن را شناسایی کرده و به 755 مشخص کنید)، و inline + می‌گوید که شما محتوای آن را بلافاصله بعد از این خط فهرست خواهید کرد. + متد inline_data شما به این شکل به نظر می‌رسد:

+
+
+
def inline_data(file, code = 'M', mode = '644')
   content = File.read(file)
   puts "#{code} #{mode} inline #{file}"
   export_data(content)
 end
-
-
-
-

You reuse the export_data method you defined earlier, because it’s the same as the way you specified your commit message data.

-
-
-

The last thing you need to do is to return the current mark so it can be passed to the next iteration:

-
-
-
-
return mark
-
-
-
- - - - - -
-
یادداشت
-
-
-

If you are running on Windows you’ll need to make sure that you add one extra step. -As mentioned before, Windows uses CRLF for new line characters while git fast-import expects only LF. -To get around this problem and make git fast-import happy, you need to tell ruby to use LF instead of CRLF:

-
-
-
-
$stdout.binmode
-
-
-
-
-
-

That’s it. -Here’s the script in its entirety:

-
-
-
+
+
+
+

شما از متد export_data که قبلاً تعریف کرده‌اید استفاده می‌کنید، زیرا این همان روشی است که داده‌های + پیام کامیت خود را مشخص کرده‌اید.

+
+
+

آخرین چیزی که باید انجام دهید این است که علامت فعلی را برگردانید تا بتوانید آن را به تکرار بعدی منتقل کنید:

+
+
+
+
return mark
+
+
+
+ + + + + +
+
یادداشت
+
+
+

اگر شما در حال اجرای ویندوز هستید، باید مطمئن شوید که یک مرحله اضافی اضافه کنید. + همانطور که قبلاً ذکر شد، ویندوز برای کاراکترهای خط جدید از CRLF استفاده می‌کند در حالی که git + fast-import فقط LF را انتظار دارد. + برای دور زدن این مشکل و خوشحال کردن git fast-import، شما باید به Ruby بگویید که از LF به + جای CRLF استفاده کند:

+
+
+
+
$stdout.binmode
+
+
+
+
+
+

این همه است. + در اینجا اسکریپت به طور کامل آمده است:

+
+
+
#!/usr/bin/env ruby
 
 $stdout.binmode
@@ -1020,25 +1130,25 @@ 

A Custom Importer

mark end -# Loop through the directories +# حلقه از طریق دایرکتوری‌ها last_mark = nil Dir.chdir(ARGV[0]) do Dir.glob("*").each do |dir| next if File.file?(dir) - # move into the target directory + # به دایرکتوری هدف بروید Dir.chdir(dir) do last_mark = print_export(dir, last_mark) end end end
-
-
-
-

If you run this script, you’ll get content that looks something like this:

-
-
-
+
+
+
+

اگر این اسکریپت را اجرا کنید، محتوایی به شکل زیر خواهید داشت:

+
+
+
$ ruby import.rb /opt/import_from
 commit refs/heads/master
 mark :1
@@ -1063,14 +1173,16 @@ 

A Custom Importer

puts "Hey there" M 644 inline README.md (...)
-
-
-
-

To run the importer, pipe this output through git fast-import while in the Git directory you want to import into. -You can create a new directory and then run git init in it for a starting point, and then run your script:

-
-
-
+
+
+
+

برای اجرای واردکننده، این خروجی را از طریق git fast-import در حالی که در دایرکتوری گیت هستید که + می‌خواهید به آن وارد کنید، هدایت کنید. + شما می‌توانید یک دایرکتوری جدید ایجاد کنید و سپس در آن git init را اجرا کنید تا نقطه شروعی داشته + باشید، و سپس اسکریپت خود را اجرا کنید:

+
+
+
$ git init
 Initialized empty Git repository in /opt/import_to/.git/
 $ ruby import.rb /opt/import_from | git fast-import
@@ -1087,7 +1199,7 @@ 

A Custom Importer

atoms: 2 Memory total: 2344 KiB pools: 2110 KiB - objects: 234 KiB + objects: 234 KiB --------------------------------------------------------------------- pack_report: getpagesize() = 4096 pack_report: core.packedGitWindowSize = 1073741824 @@ -1097,15 +1209,15 @@

A Custom Importer

pack_report: pack_open_windows = 2 / 2 pack_report: pack_mapped = 1457 / 1457 ---------------------------------------------------------------------
-
-
-
-

As you can see, when it completes successfully, it gives you a bunch of statistics about what it accomplished. -In this case, you imported 13 objects total for 4 commits into 1 branch. -Now, you can run git log to see your new history:

-
-
-
+
+
+
+

همانطور که می‌بینید، وقتی که با موفقیت کامل می‌شود، به شما تعدادی آمار درباره آنچه که انجام داده است می‌دهد. + در این مورد، شما در مجموع 13 شیء برای 4 کامیت به 1 شاخه وارد کرده‌اید. + اکنون، می‌توانید git log را اجرا کنید تا تاریخچه جدید خود را ببینید:

+
+
+
$ git log -2
 commit 3caa046d4aac682a55867132ccdfbe0d3fdee498
 Author: John Doe <john@example.com>
@@ -1118,25 +1230,27 @@ 

A Custom Importer

Date: Mon Feb 3 01:00:00 2014 -0700 imported from back_2014_02_03
-
-
-
-

There you go – a nice, clean Git repository. -It’s important to note that nothing is checked out – you don’t have any files in your working directory at first. -To get them, you must reset your branch to where master is now:

-
-
-
+
+
+
+

این است – یک مخزن گیت زیبا و تمیز. + مهم است که توجه داشته باشید که هیچ چیزی چک‌اوت نشده است – شما در ابتدا هیچ فایلی در دایرکتوری کاری خود ندارید. + برای دریافت آن‌ها، باید شاخه خود را به جایی که master اکنون است بازنشانی کنید:

+
+
+
$ ls
 $ git reset --hard master
 HEAD is now at 3caa046 imported from current
 $ ls
 README.md main.rb
-
-
-
-

You can do a lot more with the fast-import tool – handle different modes, binary data, multiple branches and merging, tags, progress indicators, and more. -A number of examples of more complex scenarios are available in the contrib/fast-import directory of the Git source code.

-
-
- \ No newline at end of file +
+
+
+

شما می‌توانید کارهای بیشتری با ابزار fast-import انجام دهید – حالت‌های مختلف، داده‌های باینری، + چندین شاخه و ادغام، برچسب‌ها، نشانگرهای پیشرفت و بیشتر. + تعدادی از مثال‌های سناریوهای پیچیده‌تر در دایرکتوری contrib/fast-import کد منبع گیت موجود است.

+
+
+ +
\ No newline at end of file