৫.২ ডিস্ট্রিবিউটেড গিট – একটি প্রজেক্টে কন্ট্রিবিউট করা
প্রজেক্টে কন্ট্রিবিউটশন
প্রথম ভেরিয়েবলটি হল একটিভ কন্ট্রিবিউটর কাউন্টঃ কতজন ব্যবহারকারী সক্রিয়ভাবে এই প্রজেক্ট এ কোড কন্ট্রিবিউট করছেন, এবং কতবার? অনেক ক্ষেত্রে, আপনার কাছে দিনে কয়েকটি কমিট সহ দুই বা তিনজন ডেভেলপার থাকবে, অথবা কিছুটা সুপ্ত প্রজেক্ট এর জন্য জন্য সম্ভবত কিছু টা কম থাকতে পারে। বৃহত্তর কোম্পানি বা প্রজেক্ট এর জন্য, ডেভেলপারের সংখ্যা হাজার হাজার হতে পারে, প্রতিদিন শত শত বা হাজার হাজার কমিট আসে। এটি গুরুত্বপূর্ণ কারণ, আরও বেশি ডেভেলপারের সাথে, আপনার কোড পরিষ্কারভাবে এপ্লাই বা সহজেই মার্জ করা যায় কিনা তা নিশ্চিত করতে আপনি আরও সমস্যার সম্মুখীন হন। আপনার সাবমিট করা পরিবর্তনগুলি গুরুতরভাবে ভেঙে যেতে পারে যা আপনি কাজ করার সময় মার্জ হয়েছিল বা যখন আপনার পরিবর্তনগুলি ওয়েটিং এ বা এপ্রুভ হওয়ার অপেক্ষায় ছিল। কিভাবে আপনি আপনার কোড ধারাবাহিকভাবে আপ টু ডেট এবং আপনার কমিটগুলো বৈধ রাখতে পারেন?
পরবর্তী ভেরিয়েবলটি হল চুজেন ওয়ার্কফ্লোঃ এটি কি সেন্ট্রালাইজড রয়েছে? প্রতিটি ডেভেলপারের মূল কোডলাইনে সমানভাবে রাইট অ্যাক্সেস রয়েছে কি? প্রজেক্ট এর কি মেইন্টেইনার বা ইন্টিগ্রেশন ম্যানেজার রয়েছে, যিনি সবগুলো প্যাচ চেক করবেন? প্রত্যেকটি প্যাচ কি পিয়ার রিভিউ এবং এপ্রুভ হয়েছে? আপনি কি এই প্রক্রিয়ার সাথে জড়িত? এখানে কি লেফটেন্যান্ট সিস্টেম আছে এবং অপনার কি প্রথমে তাদের কাছে কাজ জমা দিতে হবে?
পরবর্তী ভেরিয়েবলটি হল কমিট অ্যাক্সেসঃ একটি প্রজেক্ট এ কন্ট্রিবিউট করার জন্য প্রয়োজনীয় ওয়ার্কফ্লো অনেকটাই আলাদা হয় যদি আপনার প্রজেক্ট এ রাইট এক্সেস থাকে। যদি আপনার রাইট অ্যাক্সেস ই না থাকে, তাহলে প্রজেক্ট কীভাবে আপনার কন্ট্রিবিউটেড কাজগুলো এক্সেপ্ট করবে? এটারও কি কোনো পলিসি আছে? আপনি এট এ টাইম কত গুলো কন্ট্রিবিউট করেছেন? কত ঘন ঘন আপনি কন্ট্রিবিউট করেন?
উপরের এই প্রশ্নগুলি ই বলে দেয় আপনি কিভাবে একটি প্রজেক্ট এ কার্যকরভাবে কন্ট্রিবিউট করতে পারেন এবং কোন ওয়ার্কফ্লোগুলি আপনার জন্য উপযুক্ত। আমরা এইগুলির প্রতিটি দিক একটি সিরিজ হিসেবে কভার করব। সহজ থেকে ধীরে ধীরে জটিল উদাহরণ দেখব। এই উদাহরণগুলি থেকে আপনি প্রয়োজনীয় ওয়ার্কফ্লো তৈরি করতে সক্ষম হবেন।
কমিট গাইডলাইন
আমরা নির্দিষ্ট উদাহরণ শুরু করার আগে, এখানে কমিট সম্পর্কে একটি কুইক নোট রয়েছে। কমিট তৈরি করার জন্য একটি ভাল নির্দেশিকা থাকা এবং এতে লেগে থাকা গিট-এর সাথে কাজ করা এবং অন্যদের সাথে সহযোগিতা করা যা সবকিছু সহজ করে তোলে। গিট প্রজেক্টটি এমন একটি ডকুমেন্ট প্রদান করে যা প্যাচ সাবমিট করার জন্য এবং কমিট তৈরি করার জন্য বেশ কয়েকটি ভাল টিপস দেয়। আপনি গিট সোর্স কোড এ এটি পড়ে দেখতে পারেন। এটি Documentation/SubmittingPatches ফাইলে রয়েছে। প্রথমত, আপনার সাবমিশনগুলোতে কোনো “হোয়াইট স্পেস ত্রুটি (whitespace error)” থাকা উচিত নয়। গিট এটি পরীক্ষা করার একটি সহজ উপায় প্রদান করে — আপনি কমিট করার আগে, git diff –check এই কমান্ড টি রান করুন, যা সম্ভাব্য হোয়াইটস্পেস ত্রুটি সনাক্ত করে এবং সেগুলি আপনার জন্য তালিকাভুক্ত করে।এরপর, প্রতিটি কমিটকে যৌক্তিকভাবে পৃথক একটি “পরিবর্তন সেট” করার চেষ্টা করুন। আপনি যদি পারেন, আপনার পরিবর্তনগুলি মিনিংফুল করার চেষ্টা করুন — পাঁচটি ভিন্ন বিষয়ে পুরো সপ্তাহজুড়ে কোড করবেন না এবং তারপরে সোমবারে একটি বিশাল কমিট হিসাবে সেগুলি জমা দেওয়ার প্রয়োজন নেই। এমনকি যদি আপনি সপ্তাহজুড়ে কমিট না করে থাকেন, তবে স্টেজিং এরিয়া ব্যাবহার করে প্রতি কমিট এ একটি প্রয়োজনীয় মেসেজ সহ প্রতি ইস্যুতে কমপক্ষে একটি কমিট করুন। যদি কিছু পরিবর্তন একই ফাইলে হয়, তাহলে git add –patch ব্যবহার করার চেষ্টা করুন যাতে করে আংশিকভাবে ফাইলগুলো স্টেজ এ রাখা যায়। (আরও বিস্তারিত এই লিংকে দেয়া আছে Interactive Staging)। যতক্ষন না আপনি কিছু চেঞ্জেস এড করছেন ততক্ষন পর্যন্ত প্রতিটি ব্রাঞ্চ এর অগ্রভাগে বা রুট এ প্রজেক্ট এর স্ন্যাপশট সম্পূর্ণ অভিন্ন, যদিও আপনি একটি বা পাচটি কমিট করেছেন। সুতরাং আপনার সহকর্মী ডেভেলপারদের যখন আপনার চেঞ্জেস বা পরিবর্তনগুলি রিভিউ করতে হবে তখন তাদের জন্য প্রতিটি চেঞ্জেস এবং কমিট সহজ করার চেষ্টা করুন।
এই পদ্ধতিটি আপনার যদি পরে প্রয়োজন হয় তবে চেঞ্জসেটগুলোর যেকোনো একটিকে পুল আউট করা বা রিভার্ট করা সহজ হয়ে যায়। Rewriting History এখানেহিস্টোরি পুনরায় রি রাইট এবং ইন্টারেক্টিভভাবে ফাইল স্টেজ করার জন্য বেশ কয়েকটি দরকারী গিট এর কৌশল রয়েছে — অন্য কাউকে কাজ দেয়ার আগে একটি পরিষ্কার এবং বোধগম্য হিস্টোরি তৈরি করতে এই টুলগুলি ব্যবহার করুন৷
সর্বশেষ যে জিনিসটি মনে রাখতে হবে তা হলো কমিট মেসেজ। মানসম্পন্ন কমিট মেসেজ তৈরি করার অভ্যাস করলে, গিট এর সাথে কোলাবোরেট করা এবং এর সাথে কাজ করা অনেক সহজ হয়ে যায়। একটি সাধারণ নিয়ম হিসাবে, আপনার মেসেজগুলি একটি একক লাইন দিয়ে শুরু হওয়া উচিত যা প্রায় ৫০ অক্ষরের বেশি নয় এবং যা সংক্ষিপ্তভাবে চেঞ্জসেটগুলিকে বর্ণনা করে, এরপরে একটি ফাকা লাইন থাকে ও কিছু বিশদ ব্যাখ্যা থাকে। গিট প্রজেক্টে এর জন্য আরও বিশদ ব্যাখ্যার প্রয়োজন যেখানে আপনার পূর্ববর্তী চেঞ্জগুলোর সাথে আপনার মোটিভেশন কি ছিলো, তা উল্লেখিত থাকবে — এটি অনুসরণ করার জন্য একটি ভাল গাইডলাইন। অপনার কমিট মেসেজটি imperative sentence এ লিখুন যেমনঃ “Fix bug” কিন্তু “Fixed bug” অথবা “Fixes Bug” এভাবে লিখা উচিৎ নয়। এখানে একটি টেমপ্লেট রয়েছে যা আপনি অনুসরণ করতে পারেন, যা আমরা originally written by Tim Pope থেকে হালকাভাবে এডাপ্ট করে নিয়েছি।
Capitalized, short (50 chars or less) summary
More detailed explanatory text, if necessary. Wrap it to about 72
characters or so. In some contexts, the first line is treated as the
subject of an email and the rest of the text as the body. The blank
line separating the summary from the body is critical (unless you omit
the body entirely); tools like rebase will confuse you if you run the
two together.
Write your commit message in the imperative: "Fix bug" and not "Fixed bug"
or "Fixes bug." This convention matches up with commit messages generated
by commands like git merge and git revert.
Further paragraphs come after blank lines.
- Bullet points are okay, too
- Typically a hyphen or asterisk is used for the bullet, followed by a
single space, with blank lines in between, but conventions vary here
- Use a hanging indent
সংক্ষেপ করার জন্য, এই বই এর অনেক কমিট মেসেজ এর উদাহরণ সুন্দরভাবে ফরম্যাট করা সম্ভব হয়নি।এর পরিবর্তে, আমরা সহজভাবে -m option টি ইউজ করেছি git commit করার জন্য।
সংক্ষেপে আমরা বলি, do as we say, not as we do.
ব্যাক্তিগত ছোট টিম
আপনি যে সহজতম সেটআপের মুখোমুখি হতে পারেন তা হল এক বা দুইজন ডেভেলপারের সাথে একটি প্রাইভেট বা ব্যক্তিগত প্রজেক্ট। প্রাইভেট বা ব্যক্তিগত বলতে ক্লোজড প্রজেক্ট বুঝানো হয়েছে — যেটি আউটসাইড ওয়ার্ল্ড এ এক্সেস করা সম্ভব নয়। চাইলেই যে কেউ এই প্রজেক্ট এ এক্সেস করতে পারবে না। শুধুমাত্র আপনি এবং আপনার সহযোগী ডেভেলপারদের সকলের পুশ এক্সেস রয়েছে।এই এনভাইরনমেন্টে, আপনি সাবভারশন বা অন্য সেন্ট্রালাইজড সিস্টেম ব্যবহার করার সময় আপনি যা যা করতে পারেন তার অনুরূপ একটি ওয়ার্কফ্লো অনুসরণ করতে পারেন। তাহলে আপনি একইভাবে অফলাইন কমিটিং এবং ব্যাপকভাবে সহজ ব্রাঞ্চিং এবং মার্জ করার মতো জিনিসগুলির সুবিধাগুলি পাবেন। প্রধান পার্থক্য হল যে মার্জগুলি কমিট এর সময়ে সার্ভারের পরিবর্তে ক্লায়েন্ট-সাইডে ঘটে। দেখা যাক দুইজন ডেভেলপার যখন একটি শেয়ার্ড রিপোজিটরির সাথে একসাথে কাজ করা শুরু করে তখন এটি কেমন হতে পারে। প্রথম ডেভেলপার, জন, রিপোজিটরি ক্লোন করে, একটি ফাইলে চেঞ্জ করে এবং লোকালি কমিট করে। প্রোটোকল মেসেজগুলিকে কিছুটা সংক্ষিপ্ত করতে এই উদাহরণগুলিতে … এর সাথে রিপ্লেস করা হয়েছে।
# John's Machine
$ git clone john@githost:simplegit.git
Cloning into 'simplegit'...
...
$ cd simplegit/
$ vim lib/simplegit.rb
$ git commit -am 'Remove invalid default value'
[master 738ee87] Remove invalid default value
1 files changed, 1 insertions(+), 1 deletions(-)
# Jessica's Machine
$ git clone jessica@githost:simplegit.git
Cloning into 'simplegit'...
...
$ cd simplegit/
$ vim TODO
$ git commit -am 'Add reset task'
[master fbff5bc] Add reset task
1 files changed, 1 insertions(+), 0 deletions(-)
# Jessica's Machine
$ git push origin master
...
To jessica@githost:simplegit.git
1edee6b..fbff5bc master -> master
উপরের আউটপুটের শেষ লাইনটি পুশ অপারেশন থেকে একটি দরকারী রিটার্ন মেসেজ দেখায়। বেসিক ফর্মেট টি হল <oldref>..<newref> fromref → toref, যেখানে oldref এর মানে হল old reference, newref মানে হলো new reference, fromref হল লোকাল রেফারেন্সের নাম যা পুশ করা হচ্ছে এবং toref হল রিমোট রেফারেন্সের নাম আপডেট করা হচ্ছে। আপনি নীচের আলোচনায় অনুরূপ আউটপুট দেখতে পাবেন। এগুলোর মিনিং সম্পর্কে প্রাথমিক ধারণা থাকা রিপোজিটরির বিভিন্ন অবস্থা বুঝতে সাহায্য করবে। আরও ডিটেইলস ডকুমেন্টেশন git-push এ রয়েছে।
এই উদাহরণটি চালিয়ে, কিছুক্ষণ পরে, জন কিছু পরিবর্তন করে, সেগুলিকে তার লোকাল রিপোজিটরিতে কমিট করে এবং সেগুলিকে একই সার্ভারে পুশ দেওয়ার চেষ্টা করেঃ
# John's Machine
$ git push origin master
To john@githost:simplegit.git
! [rejected] master -> master (non-fast forward)
error: failed to push some refs to 'john@githost:simplegit.git'
প্রথম ধাপ হিসেবে, জন জেসিকার কাজগুলো ফেচ করে নিয়ে আসে (এটি শুধুমাত্র জেসিকার আপস্ট্রিম এর কাজগুলো ফেচ করে নিয়ে আসে, এটি এখনও জনের কাজের সাথ মার্জ করেনি)ঃ
$ git fetch origin
...
From john@githost:simplegit
+ 049d078...fbff5bc master -> origin/master
$ git merge origin/master
Merge made by the 'recursive' strategy.
TODO | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
$ git push origin master
...
To john@githost:simplegit.git
fbff5bc..72bbc59 master -> master
# Jessica's Machine
$ git fetch origin
...
From jessica@githost:simplegit
fbff5bc..72bbc59 master -> origin/master
$ git log --no-merges issue54..origin/master
commit 738ee872852dfaa9d6634e0dea7a324040193016
Author: John Smith
Date: Fri May 29 16:01:27 2009 -0700
Remove invalid default value
উপরের আউটপুট থেকে, আমরা দেখতে পাচ্ছি যে একটি সিঙ্গেল কমিট আছে যা জন তৈরি করেছে, কিন্তু জেসিকা তার লোকাল কাজে মার্জ করেনি। যদি সে origin/master কে মার্জ করে, তবে এটিই সিঙ্গেল কমিট যা তার লোকাল কাজকে মডিফাই করবে।
এখন, জেসিকা তার বিষয়ের কাজটি তার মাস্টার ব্রাঞ্চে মার্জ করতে পারে। জন এর কাজ (origin/master) তার মাস্টার ব্রাঞ্চে মার্জ করতে পারে এবং তারপর আবার সার্ভারে পুশ ব্যাক করতে পারে।
প্রথমে (তার issue54 ব্রাঞ্চ এর সমস্ত কাজ কমিট করে), জেসিকা এই সমস্ত কাজকে একীভূত করার প্রস্তুতির জন্য তার মাস্টার ব্রাঞ্চ এ ফিরে যানঃ
$ git checkout master
Switched to branch 'master'
Your branch is behind 'origin/master' by 2 commits, and can be fast-forwarded.
$ git merge issue54
Updating fbff5bc..4af4298
Fast forward
README | 1 +
lib/simplegit.rb | 6 +++++-
2 files changed, 6 insertions(+), 1 deletions(-)
$ git merge issue54
Updating fbff5bc..4af4298
Fast forward
README | 1 +
lib/simplegit.rb | 6 +++++-
2 files changed, 6 insertions(+), 1 deletions(-)
সবকিছু পরিষ্কারভাবে মার্জ হয়, এবং জেসিকার হিস্টোরি এখন এই রকম দেখাযঃ
$ git push origin master
...
To jessica@githost:simplegit.git
72bbc59..8059c15 master -> master
প্রতিটি ডেভেলপার কয়েকবার কমিট দিয়েছে এবং একে অপরের কাজ সফলভাবে মার্জ করেছে।
প্রাইভেট ম্যানেজড টিম (ব্যক্তিগত পরিচালিত দল)
এর পরবর্তী দৃশ্যে, আপনি একটি বৃহত্তর ব্যক্তিগত গ্রুপ এ কন্ট্রিবিউটরের ভূমিকাগুলো দেখবেন। আপনি এমন একটি পরিবেশে কীভাবে কাজ করবেন তা শিখবেন, যেখানে ছোট গ্রুপগুলো ফিচারগুলিতে কোলাবোরেট করে। এর পরে সেই গ্রুপ ভিত্তিক কন্ট্রিবিউশনগুলি অন্য পক্ষ দ্বারা ইন্টিগ্রেট হয়।ধরা যাক জন এবং জেসিকা একটি ফিচার এ একসাথে কাজ করছেন, (চলুন এটাকে আমরা “featureA” নামে ডাকি)। অন্যদিকে জেসিকা এবং তৃতীয় একজন ডেভেলভার, জোসি, দ্বিতীয় একটি ফিচার (এটিকে featureB নামে ডাকি) এ কাজ করছেন। এই ক্ষেত্রে, কোম্পানিটি একটি ইন্টিগ্রেশন-ম্যানেজার ওয়ার্কফ্লো ব্যবহার করছে, যেখানে ইনডিভিজুয়াল গ্রুপের কাজ কিছু নির্দিষ্ট ইঞ্জিনিয়ারদের দ্বারা ইন্টিগ্রেট করা হচ্ছে এবং মেইন রিপো’র মাস্টার ব্রাঞ্চ কে কেবল উক্ত ইঞ্জিয়ারদের দারাই আপডেট করা যেতে পারে। এই পরিস্থিতিতে, সমস্ত কাজ টীম-ভিত্তিক ব্রাঞ্চে করা হয় এবং পরে ইন্টিগ্রেটরদের দ্বারা পুল(Pull) বা একত্রিত করা হয়।
চলুন আমরা জেসিকার কাজের ফাংশনটি ফলো করি,, যেহেতু তারা এখানে দুইটি ফিচারে কাজ করছে এবং দুটি ভিন্ন ডেভেলপারের সাথে প্যারালেল কোলাবোরেটিং করছে। ধারণা করা যাক, তিনি ইতোমধ্যেই তার রিপোজিটরিটি ক্লোন করেছেন, তিনি প্রথমে featureA তে কাজ করার সিদ্ধান্ত নিয়েছেন। তিনি ফিচারের জন্য একটি নতুন ব্রাঞ্চ তৈরি করেছেন এবং সেখানে কিছু কাজ করেছেন।
# Jessica's Machine
$ git checkout -b featureA
Switched to a new branch 'featureA'
$ vim lib/simplegit.rb
$ git commit -am 'Add limit to log function'
[featureA 3300904] Add limit to log function
1 files changed, 1 insertions(+), 1 deletions(-)
$ git push -u origin featureA
...
To jessica@githost:simplegit.git
* [new branch] featureA -> featureA
# Jessica's Machine
$ git fetch origin
$ git checkout -b featureB origin/master
Switched to a new branch 'featureB'
$ vim lib/simplegit.rb
$ git commit -am 'Make ls-tree function recursive'
[featureB e5b0fdc] Make ls-tree function recursive
1 files changed, 1 insertions(+), 1 deletions(-)
$ vim lib/simplegit.rb
$ git commit -am 'Add ls-files'
[featureB 8512791] Add ls-files
1 files changed, 5 insertions(+), 0 deletions(-)
$ git fetch origin
...
From jessica@githost:simplegit
* [new branch] featureBee -> origin/featureBee
$ git merge origin/featureBee
Auto-merging lib/simplegit.rb
Merge made by the 'recursive' strategy.
lib/simplegit.rb | 4 ++++
1 files changed, 4 insertions(+), 0 deletions(-)
$ git push -u origin featureB:featureBee
...
To jessica@githost:simplegit.git
fba9af8..cd685d1 featureB -> featureBee
হঠাত জেসিকা জন এর কাছ থেকে একটি ইমেইল পেল। জেসিকা কে বলা হল featureA ব্রাঞ্চ এ কিছু চেঞ্জ পুশ করা হয়েছে, যেখানে তারা কোলাবোরেট করছে। সে জেসিকাকে এটি দেখতে বলল। এরপর জেসিকা আবারও “git fetch” কমান্ডটি রান করল যাতে জনের সকল কন্টেন্ট সার্ভার থেকে চলে আসে।
$ git fetch origin
...
From jessica@githost:simplegit
3300904..aad881d featureA -> origin/featureA
$ git log featureA..origin/featureA
commit aad881d154acdaeb2b6b18ea0e827ed8a6d671e6
Author: John Smith
Date: Fri May 29 19:57:33 2009 -0700
Increase log output to 30 from 25
$ git checkout featureA
Switched to branch 'featureA'
$ git merge origin/featureA
Updating 3300904..aad881d
Fast forward
lib/simplegit.rb | 10 +++++++++-
1 files changed, 9 insertions(+), 1 deletions(-)
$ git commit -am 'Add small tweak to merged content'
[featureA 774b3ed] Add small tweak to merged content
1 files changed, 1 insertions(+), 1 deletions(-)
$ git push
...
To jessica@githost:simplegit.git
3300904..774b3ed featureA -> featureA
ফর্ক করা পাবলিক প্রোজেক্ট
পাবলিক প্রোজেক্ট এ কন্ট্রিবিউট করা একটু আলাদা। কারণ সরাসরি প্রোজেক্ট এর ব্রাঞ্চে আপনার আপডেট করার অনুমতি নেই। আপনাকে অন্য কোনো উপায়ে মেইন্টেইনারদের কাছে কাজ পাঠাতে হবে। প্রথম উদাহরণটি সহজভাবে ফর্কিং এর মাধ্যমে গিট হোস্ট এ কন্ট্রিবিউট করাকে সমর্থন করে। অনেক হোস্টিং সাইটগুলো এটি সাপোর্ট করে (যেমনঃ GitHub, BitBucket, repo.or.cz এবং আরও অনেক রয়েছে) এবং অনেক প্রোজেক্ট মেইন্টেইনাররা এই কন্ট্রিবিউশনের এই স্টাইলগুলো এক্সপেক্ট করে। পরবর্তী অনুচ্ছেদটি প্রোজেক্টগুলোর সাথে এমনভাবে ডিল করে যা ই-মেইলের মাধ্যমে কন্ট্রিবিউটেড প্যাচ গ্রহণ প্রেফার করে।প্রথমত আপনি হয়তো মেইন রিপোজিটরি ক্লোন করতে পছন্দ করবেন। একটি প্যাচ বা প্যাচ সিরিজ এর জন্য একটি টপিক ব্রাঞ্চ তৈরি করুন, যেটি আপনি প্ল্যান করেছেন এবং সেখানে আপনার প্রেফারেবল কাজগুলো করুন। এই সিকুন্সটি সাধারণত এরকম হয়ঃ
$ git clone
$ cd project
$ git checkout -b featureA
... work ...
$ git commit
... work ...
$ git commit
মেইন্টেইনারদের জন্য প্যাচ ইজি করার ক্ষেত্রে, কমিটগুলোতে আপনি হয়ত আপনার কাজকে squash অথবা রিএরেঞ্জ করার জন্য rebase -i ইউজ করতে চাচ্ছেন । রিবেইজিং এর জন্য এই Rewriting History তে দেখুন আরও ইনফরমেশন রয়েছে।
$ git remote add myfork
যে কোনো ইভেন্টে আপনার কাজগুলোকে এইভাবে পুশ করতে পারেনঃ
git push -u myfork featureA
Git request-pull কমান্ডটি আপনার টোপিক ব্রাঞ্চটি যে ব্রাঞ্চে পুল করতে চান তার বেইজ ব্রাঞ্চ এবং যেখান থেকে আপনি পুল করতে চান তার গিট রিপোজিটরি url নেয়, এবং সকল change summary প্রডিউস করে যেগুলো আপনি পুল করতে বলেছেন। যেমনঃ জেসিকা জনকে একটি পুল রিকুয়েস্ট দিতে চায়, এবং সে টপিক ব্রাঞ্চে দুইটি কমিট করেছে এবং সদ্যমাত্র পুশ করেছে। তিনি এটি রান করতে পারেনঃ
$ git request-pull origin/master myfork
The following changes since commit 1edee6b1d61823a2de3b09c160d7080b8d1b3a40:
Jessica Smith (1):
Create new function
are available in the git repository at:
git://githost/simplegit.git featureA
Jessica Smith (2):
Add limit to log function
Increase log output to 30 from 25
lib/simplegit.rb | 10 +++++++++-
1 files changed, 9 insertions(+), 1 deletions(-)
যেকোন একটি প্রোজেক্টে আপনি যদি মেইন্টেইনার না হন, তাহলে সাধারণত একটি মেইন ব্রাঞ্চ (যেমন master) রাখা উচিৎ যা সবসময় origin/master কে ট্র্যাক করে এবং আপনার কাজগুলো টপিক ব্রাঞ্চ এ রাখা উচিৎ যাতে যেকোন সময় এটি ডিসকার্ড করা যায় যদি তা রিজেক্টেড হয়। যদি মেইন রিপোজিটরি ইতিমধ্যে সামনে চলে যায়, বা আপডেটেড হয়ে যায় তবে আপনার কমিটগুলো সঠিকভাবে এপ্লাই হবে না। তাই কাজের থিমগুলো ভাগ করে টপিক ব্রাঞ্চ তৈরি করলে কাজগুলোকে সহজভাবে রিবেইজ করা যায়। উদাহরণস্বরূপ, আপনি যদি সেকেন্ড টপিকের কাজটি সাবমিট করতে চান, তবে আপনি টপিক ব্রাঞ্চ এ কাজ করা থেকে বিরত থাকুন যেখানে আপনি সদ্যমাত্র পুশ করেছেন। – আপনি মেইন ব্রাঞ্চ master থেকে পুনরায় শুরু করুনঃ
$ git checkout -b featureB origin/master
... work ...
$ git commit
$ git push myfork featureB
$ git request-pull origin/master myfork
... email generated request pull to maintainer ...
$ git fetch origin
$ git checkout featureA
$ git rebase origin/master
$ git push -f myfork featureA
এটি আপনার হিস্টোরিগুলো কে rewrite করে যাতে করে এখন (“featureA work”) এর কাজ (“Commit history after”) এর মত দেখায়।
এটি আপনার হিস্টোরিগুলো কে rewrite করে যাতে করে এখন (“featureA work”) এর কাজ (“Commit history after”) এর মত দেখায়।
চলুন আরও একটি পসিবল সিনারিও দেখিঃ মেইন্টেইনার আপনার সেকেন্ড ব্রাঞ্চটি দেখলো এবং কন্সেপ্টটি পছন্দ করল, কিন্তু কিছু ইমপ্লিমেন্টেশন ডিটেইল চেঞ্জ করতে বলল। আপনিও অবশ্যই এই সুযোগে প্রোজেক্ট এর বর্তমান master ব্রাঞ্চ থেকে আপনার ব্রাঞ্চটি মার্জ করে নিবেন। আপনি একটি origin/master ব্রাঞ্চ থেকে একটি নতুন ব্রাঞ্চ (featureB) তৈরি করবেন এবং featureB এর চেঞ্জগুলো squash করে নিবেন। এরপর সবগুলো কনফ্লিক্ট resolve করবেন এবং ইম্পিমেন্টেশন চেঞ্জগুলো করুন। সবশেষে এটি নতুন ব্রাঞ্চ হিসেবে পুশ করুন।
$ git checkout -b featureBv2 origin/master
$ git merge --squash featureB
... change implementation ...
$ git commit
$ git push myfork featureBv2
এই পয়েন্টে, আপনি মেইন্টেইনারকে জানাতে পারেন যে, আপনি রিকুয়েস্টেড চেঞ্জগুলো করে ফেলেছেন এবং তারা আপনার সেই চেঞ্জেস গুলো খুজে বের করতে পারবে আপনার featureBv2 এই ব্রাঞ্চটিতে।
ফর্ক করা পাবলিক প্রোজেক্ট
পাবলিক প্রোজেক্ট এ কন্ট্রিবিউট করা একটু আলাদা। কারণ সরাসরি প্রোজেক্ট এর ব্রাঞ্চে আপনার আপডেট করার অনুমতি নেই। আপনাকে অন্য কোনো উপায়ে মেইন্টেইনারদের কাছে কাজ পাঠাতে হবে। প্রথম উদাহরণটি সহজভাবে ফর্কিং এর মাধ্যমে গিট হোস্ট এ কন্ট্রিবিউট করাকে সমর্থন করে। অনেক হোস্টিং সাইটগুলো এটি সাপোর্ট করে (যেমনঃ GitHub, BitBucket, repo.or.cz এবং আরও অনেক রয়েছে) এবং অনেক প্রোজেক্ট মেইন্টেইনাররা এই কন্ট্রিবিউশনের এই স্টাইলগুলো এক্সপেক্ট করে। পরবর্তী অনুচ্ছেদটি প্রোজেক্টগুলোর সাথে এমনভাবে ডিল করে যা ই-মেইলের মাধ্যমে কন্ট্রিবিউটেড প্যাচ গ্রহণ প্রেফার করে।প্রথমত আপনি হয়তো মেইন রিপোজিটরি ক্লোন করতে পছন্দ করবেন। একটি প্যাচ বা প্যাচ সিরিজ এর জন্য একটি টপিক ব্রাঞ্চ তৈরি করুন, যেটি আপনি প্ল্যান করেছেন এবং সেখানে আপনার প্রেফারেবল কাজগুলো করুন। এই সিকুন্সটি সাধারণত এরকম হয়ঃ
$ git checkout -b topicA
... work ...
$ git commit
... work ...
$ git commit
$ git format-patch -M origin/master
0001-add-limit-to-log-function.patch
0002-increase-log-output-to-30-from-25.patch
$ cat 0001-add-limit-to-log-function.patch
From 330090432754092d704da8e76ca5c05c198e71a8 Mon Sep 17 00:00:00 2001
From: Jessica Smith
Date: Sun, 6 Apr 2008 10:17:23 -0700
Subject: [PATCH 1/2] Add limit to log function
Limit log functionality to the first 20
---
lib/simplegit.rb | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/lib/simplegit.rb b/lib/simplegit.rb
index 76f47bc..f9815f1 100644
--- a/lib/simplegit.rb
+++ b/lib/simplegit.rb
@@ -14,7 +14,7 @@ class SimpleGit
end
def log(treeish = 'master')
- command("git log #{treeish}")
+ command("git log -n 20 #{treeish}")
end
def ls_tree(treeish = 'master')
--
2.1.0
মেইলিং লিস্ট এ ইমেইল করার জন্য, হয় আপনি আপনার ইমেইল প্রোগ্রাম এ ফাইলটি পেস্ট করবেন অথবা একটি command-line program এর মাধ্যমে সেন্ড করবেন। পেস্ট করলে সবসময় ফরমেটিং ইস্যু হয়। বিশেষভাবে “smarter” ক্লায়েন্টগুলোর সাথে যেগুলো নিউ লাইন এবং অন্যান্য হোয়াইট স্পেস সঠিকভাবে প্রিজার্ভ করে না। কপালগুনে, গিট এমন একটি tool প্রোভাইড করে যাতে আপনি IMAP এর মাধ্যমে সঠিকভাবে ফরমেটেড প্যাচগুলো পাঠাতে পারেন। এটি আপনার জন্য খুবই সহজ হবে। আমরা দেখাবো কিভাবে একটি প্যাচ Gmail এর মাধ্যমে পাঠাতে হয়। আপনি ডিটেইল ইন্সট্রাকশন পড়ে দেখতে পারেন সবশেষে মেনশন করা আছে গিট সোর্স এর Documentation/SubmittingPatches ফাইলে। প্রথমে ~/.gitconfig ফাইল এ আপনাকে IMAP সেকশনটি সেট আপ করতে হবে । আপনি প্রত্যেকটি ভ্যালু আলাদাভাবে সেট করতে পারবেন git config সিরিজ এর কমান্ডগুলোর মাধ্যমে অথবা আপনি ম্যানুয়ালি এড করতে পারবেন। কিন্তু পরিশেষে আপনার কনফিগ ফাইলটি এরকম দেখতে হবেঃ
[imap]
folder = "[Gmail]/Drafts"
host = imaps://imap.gmail.com
user = user@gmail.com
pass = YX]8g76G_2^sFbd
port = 993
sslverify = false
$ cat *.patch |git imap-send
Resolving imap.gmail.com... ok
Connecting to [74.125.142.109]:993... ok
Logging in...
sending 2 messages
100% (2/2) done
আপনি SMTP সার্ভারের মাধ্যমেও প্যাচগুলো সেন্ড করতে পারবেন। আগের মতই আপনি প্রত্যেক ভ্যালু আলাদা ভাবে সেট আপ করতে পারবেন git – – config কমান্ড সিরিজ এর মাধ্যমে অথবা সেন্ড মেইল সেকশনে ম্যানুয়ালি এড করতে পারবেন ~/.gitconfig ফাইল এ।
[sendemail]
smtpencryption = tls
smtpserver = smtp.gmail.com
smtpuser = user@gmail.com
smtpserverport = 587
$ git send-email *.patch
0001-add-limit-to-log-function.patch
0002-increase-log-output-to-30-from-25.patch
Who should the emails appear to be from? [Jessica Smith ]
Emails will be sent from: Jessica Smith
Who should the emails be sent to? jessica@example.com
Message-ID to be used as In-Reply-To for the first email? Y
(mbox) Adding cc: Jessica Smith from
\line 'From: Jessica Smith '
OK. Log says:
Sendmail: /usr/sbin/sendmail -i jessica@example.com
From: Jessica Smith
To: jessica@example.com
Subject: [PATCH 1/2] Add limit to log function
Date: Sat, 30 May 2009 13:29:15 -0700
Message-Id: <1243715356-61726-1-git-send-email-jessica@example.com>
X-Mailer: git-send-email 1.6.2.rc1.20.g8c5b.dirty
In-Reply-To:
References:
Result: OK
For help on configuring your system and email, more tips and tricks, and a sandbox to send a trial patch via email, go to git-send-email.io.
সারমর্ম
এই অনুচ্ছেদে, আমরা ছোট টিম এর অংশ হিসেবে closed-source প্রজেক্টে কাজ করা বা বড় পাবলিক প্রজেক্টে কোলাবোরেট করার মধ্যে পার্থক্যের ব্যাপারে বিবরণ দেয়া হয়েছে। কমিট করার আগে ওয়াইট-স্পেস ত্রুটি পরীক্ষা করতে হবে এবং একটি ভাল কমিট মেসেজ লিখতে হবে। প্যাচ ফর্ম্যাট করা এবং একটি ডেভেলপার মেইলিং লিস্টে ই-মেইল কিভাবে প্রেরণ করা হয় তা দেখানো হয়েছে। বিভিন্ন ওয়ার্কফ্লোরের মধ্যে মার্জ করার ব্যাপারেও বিবরণ দেয়া হয়েছে।পরবর্তীতে, আপনি কয়েনের উল্টো সাইড কিভাবে কাজ করে তা দেখবেন; গিট প্রজেক্ট কিভাবে মেইন্টেইন করতে হয় সেই বিষয়ে জানবেন। আপনি শিখবেন কিভাবে benevolent dictator বা integration manager হওয়া যায়।