# শুরুর আগে

**লেখক ও কন্ট্রিবিউটরদের তালিকা**\
[বিস্তারিত এখানে](https://github.com/howtocode-dev/git.howtocode.dev/graphs/contributors?type=a)

ভার্সন কন্ট্রোল (Version Control) : ভার্সন কন্টোল হচ্ছে এমন একটি পদ্ধতি যা আপনার প্রজেক্টের(project) বিভিন্ন সময়ের পরিবর্তনগুলো সংরক্ষণ করে রাখে। ভার্সন কন্ট্রোল সিস্টেমের মাধ্যমে আপনি আপনার প্রজেক্টের পূর্বের যে কোন সময়ের স্থিতীশীল অবস্থায় ফিরে যেতে পারবেন।

গিট(git): গিট হচ্ছে একটি ওপেনসোর্স(open source) ভার্সন কন্ট্রোল সিস্টেম। এর মাধ্যমে একজন ব্যবহারকারী যতবার তার পরিবর্তনগুলো কমিট(commit) করবে ততবার গিট তার সম্পূর্ণ ফাইল সংরক্ষন করে রাখবে। গিট এর একটি বড় সুবিধা হচ্ছে একটি প্রজেক্ট নিয়ে অসংখ্য ডেভেলপার(developer) একই সময় কাজ করতে পারে। আপনি চাইলে ইন্টারনেট সংযোগ ছাড়াও কাজ করতে পারবেন।

## ওপেন সোর্স

এই বইটি মূলত স্বেচ্ছাশ্রমে লেখা এবং বইটি সম্পূর্ন ওপেন সোর্স । এখানে তাই আপনিও অবদান রাখতে পারেন লেখক হিসেবে । আপনার কন্ট্রিবিউশান গৃহীত হলে অবদানকারীদের তালিকায় আপনার নাম যোগ করে দেওয়া হবে ।

এটি মূলত একটি [গিটহাব রিপোজিটোরি](https://github.com/howtocode-dev/git.howtocode.dev) যেখানে এই বইয়ের আর্টিকেল গুলো মার্কডাউন ফরম্যাটে লেখা হচ্ছে । রিপোজটরিটি ফর্ক করে পুল রিকুয়েস্ট পাঠানোর মাধ্যমে আপনারাও অবদান রাখতে পারেন ।

> **বর্তমানে বইটির কন্টেন্ট বিভিন্ন কন্ট্রিবিউটর এবং নানা রকম সোর্স থেকে সংগৃহীত এবং সংকলিত।**

\
This work is licensed under a [Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International License](http://creativecommons.org/licenses/by-nc-nd/4.0/).


# ভূমিকা

## ভার্সন কন্ট্রোল (Version Control) :

ভার্সন কন্টোল হচ্ছে এমন একটি পদ্ধতি যা আপনার প্রজেক্টের(project) বিভিন্ন সময়ের পরিবর্তনগুলো সংরক্ষণ করে রাখে। ভার্সন কন্ট্রোল সিস্টেমের মাধ্যমে আপনি আপনার প্রজেক্টের পূর্বের যে কোন সময়ের স্থিতীশীল অবস্থায় ফিরে যেতে পারবেন।

## গিট(git):

গিট হচ্ছে একটি ওপেনসোর্স(open source) ভার্সন কন্ট্রোল সিস্টেম। এর মাধ্যমে একজন ব্যবহারকারী যতবার তার পরিবর্তনগুলো কমিট(commit) করবে ততবার গিট তার সম্পূর্ণ ফাইল সংরক্ষন করে রাখবে। গিট এর একটি বড় সুবিধা হচ্ছে একটি প্রজেক্ট নিয়ে অসংখ্য ডেভেলপার(developer) একই সময় কাজ করতে পারে। আপনি চাইলে ইন্টারনেট সংযোগ ছাড়াও কাজ করতে পারবেন।

আসুন দেখে নেই গিট এর বহুল ব্যবহৃত কমান্ডগুলো(command)-

* git init -একটি নতুন রিপোজিটরি(repository) তৈরি করার জন্য।
* git clone – পূর্ব থেকে বিদ্যমান কোন রিপোজিটরির সম্পূর্ণ তথ্য ডাউনলোড করার জন্য
* git commit – অফলাইন(offline) রিপোজিটরিতে স্থায়ীভাবে কাজ সংযুক্ত করার জন্য
* git pull – রিমোট(remote) রিপোজিটরি থেকে ফাইল ডাউনলোড করে অফলাইন রিপোজিটরির সাথে merge করার জন্য
* git push – অফলাইন রিপোজিটরি থেকে ফাইল রিমোট রিপোজিটরিতে আপলোড করার জন্য

## কাজের ধাপসমূহ:

![Git Commit](/files/-LMxxr38dfY0lfjA7_AJ)

আমরা যখন লোকাল(local) রিপোজিটরিতে কোন পরিবর্তন করি তখন আমরা working directory-তে থাকি। git add কমান্ড দেয়ার পর সেটা staging area তে যায় এবং git commit কমান্ড দেয়ার পর সেটা স্থায়িভাবে লোকাল রিপোজিটরিতে যুক্ত হয়। পরবর্তিতে চাইলে সেটা রিমোট রিপোজিটরিতে git push কমান্ড দিয়ে আপলোড করে দেয়া যায়।


# ইন্সটলেশন এবং কনফিগারেশন

গিট নিয়ে কাজ শুরু করার জন্য আপনার কম্পিউটারকে গিট ব্যবহার উপযোগী করে নিতে হবে। সেজন্য আপনার কম্পিউটারে গিট ইন্সটল(install) করতে হবে। চলুন দেখে নেয়া যাক, কিভাবে গিট ইন্সটল এবং কনফিগার(configure) করে নিতে হয়।

## Windows:

১. গিট প্যাকেজটি ডাউনলোড করার জন্য এখানে [ক্লিক](http://git-scm.com/download/win) করুন।\
২. ডাউনলোড করা ফাইলটি ক্লিক করে ইন্সটল করে নিন।

## Linux:

Linux এর বিভিন্ন ডিস্ট্রো এর জন্য গিট ইন্সটল পদ্ধতি বিভিন্ন রকম। কিন্তু খুবই সহজ। ডিস্ট্রো অনুযায়ী terminal-এ নিচের কমান্ডগুলো লিখুন।

* Debian/Ubuntu &#x20;

  ```
    # apt-get install git
  ```
* Fedora &#x20;

  ```
    # yum install git
  ```
* Gentoo &#x20;

  ```
    # emerge --ask --verbose dev-vcs/git
  ```
* Arch Linux &#x20;

  ```
    # pacman -S git
  ```
* FreeBSD &#x20;

  ```
    $ cd /usr/ports/devel/git
  ```

  ```
    $make install
  ```
* Solaris 11 Express &#x20;

  ```
    $ pkg install developer/versioning/git
  ```
* OpenBSD &#x20;

  ```
    $ pkg_add git
  ```

## গিট কনফিগার

গিট কনফিগার করার মূল উদ্দেশ্য হচ্ছে, আপনি যখন গিট এর মাধ্যমে কমিট(commit) করবেন তখন কমিটের সাথে সে আপনার তথ্য সংরক্ষণ করে রাখবে। কনফিগারেশনের সময় আপনাকে শুধু আপনার user name এবং email address বলে দিতে হবে। Windows ব্যবহারকারীরা গিট ইন্সটল করার পর কম্পিউটার ডেক্সটপে gitBash নামে একটি শর্টকাট ফাইল তৈরি হবে। সেটি খুলে তাতে নিচের কমান্ডগুলো লিখুন। Linux ব্যবহারকারীরা terminal-এ কমান্ডগুলো লিখতে পারবেন।

```
git config --global user.name "Your Name Here"
```

Your Name Here এর জায়গায় আপনার নাম লিখুন।

```
git config --global user.email "your_email@youremail.com"
```

এখানে যে email address দিবেন তা অবশ্যই আপনার সার্ভার অ্যাকাউন্টের email address এর সাথে মিল থাকতে হবে। এখন আপনার কম্পিউটারটি গিট ব্যবহার উপযোগি হয়েছে। এখন থেকে আপনি আপনার কম্পিউটারে গিটের কমান্ডগুলো কাজে লাগাতে পারবেন। আমরা আমাদের সকল কমান্ড gitBash অথবা terminal-এ লিখবো।

`~/.gitconfig` ফাইল এ আপনার গ্লোবাল(global) কনফিগারেশন লেখা থাকে। আপনি যখন কোন একটি রিপোজিটরিতে `git init` কমান্ড দিবেন তখন `.git` নামের একটি ফোল্ডার তৈরি হবে। এই `.git` ফোল্ডারের ভিতরেই গিট সব তথ্য সংরক্ষিত রাখে।

আপনি কোন একটি রিপজিটরির জন্য গিটের গ্লোবাল কনফিগারেশনকে পরিবর্তন অথবা ওভাররাইট করতে পারেন। আপনি যদি কোন একটি রিপজিটরির জন্য `name` এবং `email` পরিবর্তন করতে চান তাহলে terminal দিয়ে রিপজিটরিতে গিয়ে নিচের কমান্ডগুলো দেন।

```
git config --local user.name "Your Name Here"
git config --local user.email "your_email@youremail.com"
```

এখানে আপনি যে `নাম` এবং `ইমেইল` দিবেন তা শধুমাত্র এই রিপোজিটরির জন্য কনফিগার হবে। আপনার লোকাল কনফিগার `.git/config` ফাইল এ সংরক্ষিত হয়। Linux/Mac ব্যবহারকারীরা terminal-এ নিচের কমান্ড দিয়ে লোকাল কনফিগারেশন এর ফাইলটি দেখতে পারেন।

```
nano .git/config
```

ফাইল এর শেষে যদি নিচের লাইনগুলো যোগ হয় তাহলে আপনার লোকাল কনফিগার সঠিকভাবে overwrite হয়েছে।

```
[user]
        name = <your-name>
        email = <your-email>
```

আপনি নিচের কমান্ড দিয়ে আপনার গিট কনফিগারেশন একসাথে দেখতে পারবেন।

```
git config --list
```


# নতুন রিপোজিটরি

অফলাইনে গিট রিপোজিটরি ব্যবহার করার জন্য নিচের ধাপগুলো অনুসরন করুন

1. ধরুন, আপনি যদি একটি routine management system তৈরি করতে চান এবং আপনার রিপোজিটরি ফোল্ডারের নাম যদি rms দিতে চান , প্রথমে

   ‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍`mkdir rms`

   কমান্ড টি লিখুন। এখন cd ব্যবহার করে আপনার রিপোজিটরিতে প্রবেশ করতে লিখুন

   ‍`cd rms`
2. এখন

   `git init`

   কমান্ড লিখুন। এতে করে আপনার রিপোজিটরিটি গিট ব্যবহারের উপযোগি হবে এবং .git নামে একটি লুকানো ফোল্ডার তৈরি হবে। আপনার রিপোজিটরিতে .git ফোল্ডারটি তৈরি না থাকলে আপনি গিটের কমান্ডগুলো কাজে লাগাতে পারবেন না।
3. আপনার রিপোজিটরিটি এখন কাজের উপযুক্ত হয়েছে। আপনি এখন এতে যে কোন ধরনে ফাইল, ফোল্ডার তৈরি, সম্পাদনা ও মুছে ফেলতে পারবেন।
4. আপনার রিপোজিটরি প্রত্যেকবার স্থিতিশীল(stable) অবস্থায় পৌছলে সেগুলো Staging Area তে পাঠাতে হবে। Staging area তে পাঠানোর মানে হচ্ছে আপনি যে যে ফাইলগুলোকে নিশ্চিতভাবে রিপোজিটরিতে অন্তর্ভুক্ত করবেন তার তালিকা তৈরি করা। সে জন্য আপনাকে `git add` কমান্ড ব্যবহার করতে হবে। যদি আপনি বর্তমান সবগুলো ফাইলকে Staging area তে সংযুক্ত করতে চান তবে আপনাকে

   `git add --all`

   কমান্ড ব্যবহার করতে হবে। যদি একটি ফাইকে সংযুক্ত করতে চান তবে `git add` কমান্ডের পর ফাইলের নাম লিখতে হবে। ধরুন আপনি test.txt নামে একটি ফাইল তৈরি করেছেন যা আপনি Staging area তে পাঠাতে চান। তখন আপনার কমান্ড হবে

   `git add test.txt`
5. সর্বশেষ আপনাকে যে কাজটি করতে হবে তা হচ্ছে, আপনার staging area তে সংযুক্ত করা ফাইলগুলোকে মূল রিপোজিটরির সাথে নিশ্চতভাবে সংযুক্ত করা। সে জন্য আপনাকে `git commit` কমান্ডটি ব্যবহার করতে হবে। আপনাকে প্রত্যেক commit এর সাথে একটি বার্তা সংযুক্ত করে দিতে হবে। তখন আপনার সম্পূর্ণ কমান্ডটি হবে-

   `git commit -a -m "Your Message"`

   এখানে "Your Message" এর জায়গায় আপনি আপনার ইচ্ছেমত যেকোন টেক্সট দিতে পারেন।


# রিমোট রিপোজিটরি

অনলাইনে গিট রিপোজিটরি সংরক্ষণ করে রাখার জন্য কিছু সার্ভার রয়েছে। যাদের মধ্যে [GitHub](https://github.com/), [BitBucket](https://bitbucket.com), [GitLab](https://about.gitlab.com/gitlab-com/) অন্যতম। এই সব সার্ভারে সংরক্ষিত রিপোজিটরিগুলোকে রিমোট রিপোজিটরি বলা হয়। আপনি সাইটগুলোতে প্রবেশ করে আপনার নিজস্ব রিপোজিটরি তৈরি করতে পারবেন। একটি রিমোট রিপোজিটরি তৈরি করার পর আপনাকে সাধারণত আপনার লোকাল কম্পিউটার থেকেই সেগুলোকে সম্পাদনা করতে হবে। সম্পাদনা শেষে আবার রিমোট রিপোজিটরিতে আপলোড করে দিতে হবে। চলুন দেখা যাক, গিট ব্যবহার করে কিভাবে আমরা একটি রিমোট রিপোজিটরিকে সম্পাদনা করতে পারি।

(আমরা এখানে bitbucket ও ওয়েব ডেভেলপমেন্ট এর রিপোজিটরি নিয়ে আলোচনা করবো)

1. প্রথমেই আপনার রিমোট রিপোজিটরিটিকে আপনার নিজস্ব কম্পিউটারে নিয়ে আসতে হবে। এজন্য আপনাকে cd কমান্ড ব্যবহার করে আপনার কম্পিউটারের localhost এ যেতে হবে। localhost এর জন্য আপনাকে htdocs অথবা www ফোল্ডারে প্রবেশ করতে হবে।
2. ব্রাউজারের মাধ্যমে আপনার রিমোট রিপোজিটরিতে প্রবেশ করুন। সেখানে clone বাটনে ক্লিক করার পর সেখানে একটি কমান্ড দেখতে পাবেন। clone কমান্ডের দুইটি অপশন থাকে। একটি হচ্ছে https এবং অন্যটি ssh। ssh কমান্ড নির্বাচন করলে আপনার কম্পিউটারে একটি ssh key তৈরি করতে হবে। পরে সেটি আপনার সার্ভারে সংরক্ষন করতে হবে। কিন্তু https নির্বাচন করলে কোন key তৈরি করতে হবে না। চলুন দেখে নেয়া যাক, কিভাবে ssh key তৈরি করতে হয়-
   * terminal এ `ssh-keygen` কমান্ডটি লিখুন। এতে করে আপনার কম্পিউটারের home ফোল্ডারে লুকানো একটি *.ssh* ফোল্ডার তৈরি হবে এবং একটি *id\_rsa.pub* ফাইল তৈরি হবে। *id\_rsa.pub* ফাইলটি খুলুন এবং এর ভিতরের লেখাগুলো copy করুন।
   * আপনার সার্ভার account এ প্রবেশ করুন। সেখান থেকে manage account লিংকে(link) প্রবেশ করুন। এরপর সেখান থেকে ssh key লিংকে প্রবেশ করে আপনার key টি paste করুন। এরপর সংরক্ষন করে বের হয়ে আসুন।
3. সার্ভার একাউন্ট(account) থেকে clone কমান্ডটি copy করে terminal এ paste করুন।
4. আপনার clone কমান্ডটি যদি https এর হয় তাহলে আপনার কাছে আপনার একাউন্ট এর user name এবং password চাইবে। সঠিক তথ্য দিলে আপনার সার্ভারের রিপোজিটরিটি আপনার নিজস্ব কম্পিউটারে ক্লোন(clone) হয়ে যাবে। আপনার localhost এ প্রবেশ করলে সার্ভারের রিপোজিটরির নামে একটি ফোল্ডার দেখবেন। এটাই আপনার নিজস্ব কম্পিউটারে রিমোট রিপোজিটরির ক্লোন।
5. এখন অফলাইনে থেকেই আপনার রিপোজিটরিতে কাজ করুন। এরপর আপনি যখনি আপনার রিমোট রিপোজিটরিতে আপনার কোড(code) সংযুক্ত করতে চাইবেন তখন আপনাকে কিছু কমান্ড ব্যবহার করতে হবে। সেগুলো নিচে দেয়া হলো।

   * আপনার রিপোজিটরি প্রত্যেকবার স্থিতিশীল(stable) অবস্থায় পৌছলে সেগুলো Staging Area তে পাঠাতে হবে। Staging area তে পাঠানোর মানে হচ্ছে আপনি যে যে ফাইলগুলোকে নিশ্চিতভাবে রিপোজিটরিতে অন্তর্ভুক্ত করবেন তার তালিকা তৈরি করা। সে জন্য আপনাকে git add কমান্ড ব্যবহার করতে হবে। যদি আপনি বর্তমান সবগুলো ফাইলকে Staging area তে সংযুক্ত করতে চান তবে আপনাকে

   `git add *`

   কমান্ড ব্যবহার করতে হবে। যদি একটি ফাইকে সংযুক্ত করতে চান তবে git add কমান্ডের পর ফাইলের নাম লিখতে হবে। ধরুন আপনি test.txt নামে একটি ফাইল তৈরি করেছেন যা আপনি Staging area তে পাঠাতে চান। তখন আপনার কমান্ড হবে

   `git add test.txt`

   * আপনার staging area তে সংযুক্ত করা ফাইলগুলোকে মূল রিপোজিটরির সাথে নিশ্চতভাবে সংযুক্ত করা। সে জন্য আপনাকে git commit কমান্ডটি ব্যবহার করতে হবে। আপনাকে প্রত্যেক commit এর সাথে একটি বার্তা সংযুক্ত করে দিতে হবে। তখন আপনার সম্পূর্ণ কমান্ডটি হবে-

   `git commit -m “Your Message”`

   * এখন কমিট(commit) করা ফাইলগুলোকে রিমোট রিপোজিটরিতে সংযুক্ত করতে আপনাকে git push কমান্ডটি ব্যবহার করতে হবে। আপনি কোন ব্রাঞ্চ(branch (branch সম্পর্কে অন্য টিউটরিয়ালে আলোচনা করা হবে))-এ ফাইল সংযুক্ত তাও বলে দিতে হবে। আমরা আমাদের ফাইল `master` branch এ সংযুক্ত করবো। সম্পূর্ণ কমান্ডটি নিচে দেয়া হলো।

   `git push origin master`

   এখানে origin হচ্ছে রিমোট রিপোজিটরির নাম। যে রিমোট রিপোজিটরি থেকে ফাইল ক্লোন করা হয় তার নাম সাধারণত origin দেয়া থাকে।


# মাল্টিপল ডেভেলপার

সাধারণত আমরা যখন কোন প্রজেক্ট বা রিপোজিটরি নিয়ে একটি টিমে(team) কাজ করি তখন প্রজেক্ট ব্যবস্থাপনাটা একটু জটিল হয়ে যায়। বিশেষ করে একই ফাইলে একাধিক ডেভেলপার কাজ করা। এই সমস্যার সমাধানের জন্য গিট যে পদ্ধতি ব্যবহার করেছে তা এক কথায় অসাধারণ। কোন কাজ অথবা কোড না হারিয়েই একই ফাইলে কাজ করতে পারবেন অসংখ্য ডেভেলপার। একটি রিপোজিটরি নিয়ে অসংখ্য ডেভেলপার বিচ্ছিন্নভাবে কাজ করলেও সবাই সংযুক্ত থাকতে পারবেন গিট এর মাধ্যমে। কথাটা শুনতে খাপছাড়া মনে হলেও এটাই সত্যি। তাহলে দেরি না করে চলুন দেখা যাক কিভাবে একই রিপোজিটরিতে অসংখ্য ডেভেলপার কাজ করতে পারবেন। আমরা এখানে যে পদ্ধতি নিয়ে আলোচনা করবো তা অধিকাংশ ওপেনসোর্স(opensource) রিপোজিটরিতে ব্যবহার করা হয়।

* প্রথমেই আমাদেরকে এমন একটি রিমোট রিপোজিটরি তৈরি করতে হবে যা কেন্দ্রীয় রিপোজিটরি হিসেবে ব্যবহার করা হবে। আপনি যদি বিনামূল্যে github(একটি গিট রিপোজিটরি সার্ভার) ব্যবহার করেন তাহলে যে কেউ আপনার রিপোজিটরিতে read access পাবে। কিন্তু bitbucket ব্যবহার করলে আপনি যদি রিপোজিটরি public না করে দেন তাহলে কেউ দেখতে পাবে না। চাইলে আপনি private রিপোজিটরিতেও আপনার পছন্দনীয় ব্যক্তিকে read, write অথবা admin access দিতে পারবেন। তাই আপনি যে সকল ডেভেলপারকে আপনার রিপোজিটরিতে সংযুক্ত করবেন তাদেরকে read access দিন।&#x20;
* ফোর্ক(fork): admin ব্যতিত যে সকল ডেভেলপার একই রিপোজিটরিতে কাজ করবেন তাদেরকে কেন্দ্রীয় বা মূল রিপোজিটরিতে Fork করতে হবে। ফোর্ক মানে হচ্ছে ডেভেলপারের সার্ভার একাউন্টে(account) মূল রিপোজিটরির মত একটি স্বতন্ত্র রিপোজিটরি তৈরি করা। ফোর্ক করার পর ডেভেলপার যে রিপোজিটরি তৈরি করবেন তা একান্তই তার নিজস্ব। এতে মূল রিপোজিটরির সাথে দৃশ্যত কোন সম্পর্ক থাকবে না। পরবর্তীতে আমরা চাইলে মূল রিপোজিটরির সাথে সংযোগ দিতে পারবো। একটি রিপোজিটরি ফোর্ক করা খুবই সহজ-
  * কেন্দ্রীয় রিপোজিটরিতে প্রবেশ করুন – Fork বাটনে(button) ক্লিক করুন – প্রয়োজনীয় তথ্য পূরণ করে submit করুন ডেভেলপার এখন একটি নিজস্ব রিপোজিটরির মালিক। :)&#x20;
  * এখন ডেভেলপার তার নিজস্ব রিপোজিটরিতে নতুন যে কোন feature নিয়ে কাজ করতে পারবেন। করতে পারবেন যে কোন ধরনের সম্পাদনা। কাজতো হলো কিন্তু এবার এত পরিশ্রমের কাজ কিভাবে মূল রিপোজিটরির সাথে সংযুক্ত করবো? খুবই সহজ–&#x20;
  * Compare: কোন কোন রিমোট রিপোজিটরি সার্ভারে আপনার করা কাজকে compare করার সুযোগ রাখা হয়েছে। চাইলে আপনি দেখে নিতে পারেন মূল রিপোজিটরির সাথে আপনি কি সংযোজন-বিয়োজন করেছেন। compare করার জন্য ডেভেলপার তার রিপোজিটরি পাতায় compare বাটনে ক্লিক করুন। দেখে নিন আপনার কাজের বর্ণনা।&#x20;
    * Pull Request: আপনার কাজগুলো মূল রিপোজিটরিতে অন্তর্ভুক্ত করার জন্য মূল রিপোজিটরিতে একটি Pull Request পাঠাতে হবে। এতে করে মূল রিপোজিটরিতে ডেভেলপারের কাজ সংযুক্ত করার জন্য একটি বার্তা প্রেরণ করা হবে। admin চাইলে ডেভেলপারের কাজ গ্রহন অথবা বাতিল করতে পারবেন। ডেভেলপার শুধু তার কাজ গ্রহন করা হয়েছে কি বাতিল করা হয়েছে এই মর্মে একটি বার্তা পাবেন। Pull Request পাঠানোর জন্য ডেভেলপার তার রিপোজিটরি পাতায় pull request বাটনে ক্লিক করুন।
* এখন এডমিন তার মূল রিপোজিটরিতে একটি নতুন Pull Request পাবেন। কাজ পর্যবেক্ষণের পর তা গ্রহন করার মত হলে মূল রিপোজিটরির সাথে Merge করে নেবেন। উপরের যে ধাপগুলো বর্ণনা করা হয়েছে সেগুলো সম্পূর্ণ সার্ভারভিত্তিক। আপনি চাইলে সার্ভারের ওয়েব সাইটে প্রবেশ না করে গিট কমান্ড এর মাধ্যমে সরাসরি আপনার নিজস্ব কম্পিউটার থেকে ডেভেলপারদের কাজ পর্যবেক্ষণ করতে পারবেন। সেজন্য আপনাকে জানতে হবে কিভাবে আপনি একাধিক রিমোট রিপোজিটরির সাথে সংযুক্ত হবেন। আমরা আগামী টিউটরিয়ালে এ বিষয়ে আলোচনা করবো, ইনশাআল্লাহ।


# একাধিক রিমোট রিপো

একই রিপোজিটরিতে একাধিক ডেভেলপার কাজ করলে একজন ডেভেলপার অন্য একজন ডেভেলপারের কাজ pull করার প্রয়োজন হতে পারে। এছাড়াও admin যখন কোন ডেভেলপারের কাজ পর্যবেক্ষণ করবেন তখন ঐ ডেভেলপারের রিপোজিটরির সাথে admin এর রিপোজিটরির সংযোগ দিতে হবে। চলুন দেখে নেয়া যাক কিভাবে রিমোট রিপোজিটরির সাথে সংযোগ দেয়া যায়। রিমোট রিপোজিটরির সাথে সংযোগ দেয়ার জন্য আমাদেরকে git remote কমান্ডটি ব্যবহার করতে হবে। সম্পূর্ণ কমান্ডটি নিচে দেয়া হলো-

```
$ git remote add <name> <remote-repo-url>
```

এখানে name এর জায়গায় আপনি রিমোট রিপোজিটরিটিকে যে নামে ডাকতে চান সে নাম হবে। remote-repo-url এর জায়গায় রিমোট রিপোজিটরিটির HTTPS/SSH clone address দিতে হবে। ধরুন আমরা একটি কেন্দ্রীয় রিপোজিটরি তৈরি করলাম যার নাম হচ্ছে rms এবং রিপোজিটরিটির HTTPS clone address হচ্ছে <https://bitbucket.org/precursortechnology/rms.git> । এখন এতে যতজন ডেভেলপার কাজ করবে সবাই এই রিপোজিটরিটি fork করতে হবে। এখন ডেভেলপাররা যদি তাদের রিপোজিটরিকে কেন্দ্রীয় রিপোজিটরির (<https://bitbucket.org/precursortechnology/rms.git>) সাথে সংযোগ দিতে চান তাহলে তাদেরকে লিখতে হবে

```
$ git remote add upstream https://bitbucket.org/precursortechnology/rms.git
```

এখানে আমরা কেন্দ্রীয় রিপোজিটরিকে চেনার জন্য *upstream* নাম ব্যবহার করেছি। আপনি চাইলে অন্য যে কোন নাম ব্যবহার করতে পারেন। এখন নিশ্চিত হওয়ার জন্য *upstream* এর মান দেখতে পারেন।

```
$ git remote show upstream
```

একটি রিপোজিটরি চাইলে একাধিক রিমোট রিপোজিটরির সাথে সংযুক্ত হতে পারবে। সবগুলো remote এর মান একসাথে দেখার কমান্ড -

```
$ git remote -v
```

এখন কোন ডেভেলপার যদি কেন্দ্রীয় রিপোজিটরির (`upstream`) তথ্য pull করতে চান তাহলে তাকে লিখতে হবে -

```
$ git pull upstream master
```

pull করা মানে হচ্ছে ঐ রিপোজিটরির সর্বশেষ তথ্যগুলো আপনার রিপোজিটরির সাথে একীভূত করে নেয়া। pull কমান্ড দিয়ে মূলত দুটি কাজ করা হয়। প্রথমে রিমোট রিপোজিটরিটির তথ্যগুলো fetch করে নেয়া হয় এবং পরে সেগুলো লোকাল রিপোজিটরির সাথে merge করা হয়। উপরের কমান্ড দিয়ে আমরা upstream নামক রিমোট রিপোজিটরির `master` branch এর সব তথ্যগুলো/commits লোকাল repository এর বর্তমান ব্রাঞ্চ এ merge করে নিলাম।

এখন আপনার নিজের রিপোজিটরি (*origin*) তে *upstream* এর সব তথ্যগুলো পাঠাতে হলে লিখতে হবে -

```bash
$ git push origin HEAD    # এখানে HEAD = বর্তমান লোকাল ব্রাঞ্চ এর নাম।
```

যেকোন রিমোট remove করার কমান্ড `git remote rm <remote-name>` . সুতরাং, `upstream` রিমোট remove করতে হলে কমান্ড হবে -

```
$ git remote rm upstream
```

কোন রিমোট rename করার কমান্ড `git remote rename <present-name> <new-name>` . সুতরাং, `upstream` রিমোট কে `origin2` করতে হলে কমান্ড হবে -

```
$ git remote rename upstream origin2
```


# গিট-ফ্লও পরিচিতি

গিট-ফ্লো আসলে একটা শাখা(branching) মডেল, যেটা Vincent Driessen নামের একজন লোক সর্বপ্রথম বানিয়েছেন। এটা মলুত গিটের উপর নির্ভর করে বানানো হয়েছে। এর সবচেয়ে বড় সুবিধা হল একাধিক ডেভেলপার একসাথে একটা বড় প্রোজেক্ট নির্ভেজাল ভাবে কাজ করতে পারে।

কিন্তু, গিট-ফ্লো নিয়ে কাজ করতে হলে আগে, গিটের উপর ভাল দখল থাকতে হবে। গিটের শাখা (branching) কিভাবে কাজ করে সেটা ভাল করে জানতে হবে। আর এই ক্ষেত্রে, কমান্ড লাইনে (command line) এ কাজ করা সবার আগে আবশ্যক।


# গিট-ফ্লও ইন্সটলেশন এবং  কনফিগারেশন

**গিট-ফ্লও ইন্সটলেশন**&#x20;

* ডেবিয়ান নির্ভরশীল লিনাক্স সিস্টেমে গিট-ফ্লও (`git-flow`) ইন্সটল করার জন্য নিছের কমান্ডটি রান করুন

  `$ sudo apt-get install git-flow`
* ফেডরা নির্ভরশীল লিনাক্স সিস্টেমে গিট-ফ্লও (`git-flow`) ইন্সটল করার জন্য নিছের কমান্ডটি রান করুন

  `$ yum install gitflow`
* অ্যাপল নির্ভরশীল ম্যাক সিস্টেমে গিট-ফ্লও ইন্সটল করার জন্য নিছের কমান্ড রান করুন

  `$ brew install git-flow`
* উইন্ডোজ সিস্টেমে গিট-ফ্লও ইন্সটল করার জন্য সবার আগে [cygwin](http://www.cygwin.com/) ইন্সটল করুন। এটা একটা উইন্ডোজ সিস্টেমে, লিনাক্স এনভায়রোমেন্ট তৈরি করে। এরপর নিছের কমান্ডগুলো রান করুনঃ

  `$ wget -q -O - --no-check-certificate` [`https://github.com/nvie/gitflow/raw/develop/contrib/gitflow-installer.sh`](https://github.com/nvie/gitflow/raw/develop/contrib/gitflow-installer.sh) `| bash`
* যদি এরপর `git-flow init` রান করার পর কেউ `"flags: FATAL unable to determine getopt version"` এই error দেখতে পায়, তাহলে `util-linux package` ইন্সটল করতে হবে `Cygwin` দিয়ে।

আর বিস্তারিত জানতে উক্ত লিঙ্কে ক্লিক করুনঃ [উইন্ডোজ সিস্টেমে ইন্সটল গিট-ফ্লও ](https://github.com/nvie/gitflow/wiki/Windows)

**গিট-ফ্লও কনফিগার**

গিট-ফ্লও কনফিগারেশন করার জন্য সবার আগে একটা গিট রিপোজিটরি থাকতে হবে। আমরা যখন কোন একটা প্রোজেক্টে git init করি, তখন সমস্ত কাজ গুলো একটা ডিফল্ট শাখা `"মাস্টার(master)"` এ জমা হতে থাকে।

বিরক্ত লাগছে... চলুন আমরা এবার নিজে করিঃ

১। আগে আমরা একটা ফোল্ডার বানাবঃ

`mkdir git-flow-test`

২। এবার আমি একটা ফাইল বানাব git-flow-test ফোল্ডারে ডুকে।

`cd git-flow-test`

`touch helloworld.txt`

৩। এবার আমরা সবার আগে এখানে গিট `(git)` রেপোজিটোরি বানাব। এজন্য আমরা এখানে নিছের কমান্ড চালবঃ

`git init`

৪। এখন আমরা আমাদের চেঞ্জগুলো গিটে যোগ করে একটা কমিট করব। তার জন্য নিছের কমান্ডগুলো চালাবঃ

`git add .` `git commit -m "initali commit with first file"`

৫। এখন আমাদের সবগুলো পরিবর্তন গিটের প্রাথমিক ব্রাঞ্চ `master` এ আছে। এখন আমাদের গিট রিপোজিটিরি `git-flow`বানানোর জন্য তৈরি। গিট-ফ্লও বানানোর জন্য এখন আমরা নিছের কমান্ডগুলো রান করবঃ


# গিট-ফ্লওফিচার

গিট-ফ্লও ফিচার শুরু করার আগে আমরা কিছু জিনিস বানাব। যেমন আমরা কোন প্রোজেক্ট করার আগে কোন একটা প্রোজেক্ট ম্যানেজমেন্ট সিস্টেমে, প্রোজেক্ট রিলেটেড সব ফিচার (feature), বাগ (bug) ইত্যাদি আমরা বিস্তারিত লেখে রাখি। এরপর আমরা বিভিন্ন ডেভেলপারকে আমরা তা assign করে দেই।

ধরি আমাদের প্রোজেক্টের নামে হেলো `"গিট-ফ্লও (Hello Git-Flow)"` আমাদের কাছে নিন্মলিখিত ফিচারগুলো আছেঃ

* HGT-01: Bootstrap Hello Git-Flow project
* HGT-02: Create login with Username and Password
* HGT-03: Create user signup
* HGT-04: Create forget Password
* HGT-05: Homepage with login and Signup option

এখন, আমরা একটা একটা করে ফিচারে কাজ শুরু করব,`গিট-ফ্লও (git-flow) ফিচার` ব্যবহার করে।

`ধাপ-০১`

সবার আগে আমরা `HGT-01` ফিচার নিয়ে কাজ শুরু করব। এজন্য আমরা কমান্ড লিখব

```
git-flow feature start HGT-01
```

এরপর আমরা নিছের ছবির মত একটা মেসেজ দেখতে পাব,

![git-flow-feature-start](/files/-LMxxr733aRacO3sZmXf)

এখানে আমরা যেটা দেখতে পারছি, তা হোল, সবার আগে `develop` নামে যে ব্রাঞ্চ (branch) আছে, তার উপর নির্ভর করে একটা নতুন ব্রাঞ্চ (branch) `feature/HGT-01` তৈরি হয়েছে। এরপর স্বয়ংক্রিয় ভাবে,ওই ব্রাঞ্চে (branch) পয়েন্ট করে ফেলেছে।

`ধাপ-০২`

এখন আমরা ফিচার ডেভেলপমেন্টের কাজ করব এবং ক্রমান্বয়ে কমিট করব, যেভাবে আমরা গিটে (git) কমিট করতাম। আমরা যত পরিবর্তন করব, সবই আমাদের বর্তমান `ফিচার (featuere)` ব্রাঞ্চ এ যোগ হতে থাকবে। ধরি,

একটা নতুন ফাইল বানাব কারেন্ট ফিচারের জন্য

```
touch project-config.php
```

এবার এই ফাইলে কিছু পরিবর্তন করব, মানে কিছু লেখা যোগ করব

```
nano project-config.php
```

এবার আমরা ফাইলটা গিটে যোগ করব এবং গিটে কমিট করব

```
git add project-config.php
git commit -m "project configuration file is added"
```

`ধাপ-০৩`

এবার ধরে নিলাম আমাদের ফিচার `feature` ডেভেলপমেন্টের কাজ শেষ। এখন আমরা গিট-ফ্লও দিয়ে আমাদের ফিচার কমপ্লিট করব।

```
git-flow feature finish HGT-01
```

এই কমান্ড চালানোর পর আমরা নিছের ছবির মত একটা মেসেজ দেখতে পারব

![git-flow-feature-finish](/files/-LMxxr77Ja7u2UNx6alQ)

**গিট-ফ্লও ফিচার পাবলিশ**

আমরা যদি মনে করি, কোন একটা ফিচার ব্রাঞ্চে অন্য কেউ কাজ করবে, তাহলে আমারা চাইলে গিটে আপ করে দিতে পারি।এজন্য আমরা নিচের কমান্ডটা রান করবঃ

```
  git-flow feature publish HGT-01
```

এই কমান্ড চালানোর পর নিচের মত একটা স্ক্রীন দেখা যাবে।

![git-flow-feature-finish](/files/-LMxxr79duoyRI-6uHhF)


# গিট-ফ্লও রিলিস

গিট-ফ্লও এর আরেকটি প্রয়োজনীয় কমান্ড হোল গিট-ফ্লও রিলিস। এটা দিয়ে আমরা মূলত একটা development branch থেকে production সার্ভারে দেয়ার মত একটা রিলিস তৈরি করি। এটা দিয়ে আমরা খুব সহজে, একটা রিলিস এর নাম্বার দিতে পারি, যেন খুব সহজে আমরা আবার পরবর্তী কোন রিলিএসে ব্যাক করতে পারি।

আমরা যদি গিট-ফ্লও রিলিসের সিনট্যাক্স জানতে চাই, তাহলে আমরা কমান্ড লাইনে গিয়ে নিচের কমান্ড টাইপ করলে হবেঃ

```
Git-flow release (press enter)
```

এবার আমরা নিচের মত একটা স্ক্রীন দেখতে পাব।

![git-flow-feature-start](/files/-LMxxr74iIrADaNogbqv)

এখানে তিনটা টার্ম আছে, যা জানতে হবেঃ

1. &#x20;: রিলিসের নাম। যেমনঃ rel-v1.0
2. \[]: এটা একটা ব্রাঞ্চের নাম। মানে আমরা যদি development branch থেকে ব্রাঞ্চ তৈরি না করে, অন্য কোনব্রাঞ্চ থেকে রিলিস তৈরি করতে চাই, তখন ওই ব্রাঞ্চ এর নাম দিব।

এবার আমরা একটা রিলিস তৈরি করব। আমরা ধরে নিচ্ছি, আমাদের ব্রাঞ্চ development। তাহলে আর দেরি না করে নিচের কমান্ডটা রান করিঃ

```
git-flow release start rel-v1.0
```

এখন আমরা নিচের মত একটা স্ক্রীন দেখতে পাবোঃ ![git-flow-feature-start](/files/-LMxxr76rWw0AFqGDwMo)

আমরা এখন দেখতে পেলাম একটা নতুন ব্রাঞ্চ rel-v1.0 নামের একটা নুতুন ব্রাঞ্চ তৈরি হয়েছে।

আমরা এখন যেটা করতে পারি, এই ব্রাঞ্চটাকে একটা টেস্টিং সার্ভারে দিয়ে দেতে পারি। একদল QA দলকে বলতে পারি, টেস্টিং করতে। যখন, টেস্টিং শেষ হবে, আমরা রিলিসটাকে finish করে দিতে পারি।

এখন জানতে হবে, রিলিস শেষ(finish) করলে কি হয়ঃ আমরা যখনই কোন রিলিস শেষ করব, গিট-ফ্লও স্বয়ংক্রিয়ভাবে রিলিস ব্রাঞ্চের সকল কোড development branch এবং production branch (master এখানে production branch) এ merge করে দেয়।

এখন আর কথা না বাড়িয়ে, কমান্ডটা রান করে দেখিঃ

```
git-flow release finish rel-v1.0
```

এখন আমরা নিচের মত একটা স্ক্রীন দেখতে পাবোঃ

**গিট মারজ মেসেজ**

![git-flow-feature-start](/files/-LMxxr78ONug4sjzXFW4)

**গিট ট্যাগ মেসেজ** ![git-flow-feature-start](/files/-LMxxr7A3EELQdY8-tMI)

**গিট ফিনিশ শেষ** ![git-flow-feature-start](/files/-LMxxr7C55-eVogmptxu)

এখন আমরা একটু খেয়াল করে **summary of Actions** এর দিকে খেয়াল করে দেখি। এখানে আসলে গিট-ফ্লও কি কি কাজ করেছে, তার একটা সারাংশ তুলে ধরেছে। এবং সব শেষে মাস্টার ব্রাঞ্চ এ শিফট করছে। মানে, rel-v1.0 এর সকল কোড এখন (master) মাস্টার ব্রাঞ্চেও আছে এবং development ব্রাঞ্চে ও আছে।


# গিট-ফ্লও হটফিক্স


# গিট ব্রাঞ্চ

১টা ছোট্ট গল্প দিয়ে শুরু করি। কোন প্রোজেক্ট করতে গিয়ে কিছু কোড লিখে রান দিলাম, কোড কাজ করে। তখন ১টা ব্যাকআপ রাখার জন্য প্রজেক্ট ফোল্ডার জিপ করে আবার আমরা কোড লেখা শুরু করি। কিন্তু এবার কোড রান দিলে error দেখায়। কথায় ভুল হইসে অনেক সময় ঠিক করা যায় না, তখন প্রোজেক্ট ফোল্ডার ডিলিট করে ব্যাকআপ জিপ-কে আন-জিপ করে আবার কাজ করি। এই যে গল্প বললাম, এটাই গিট ব্রাঞ্চ এর কাজ। এবার আসি কিভাবে ব্রাঞ্চ কাজ করে।

প্রথমেই ১টা প্রোজেক্ট দরকার। ধরি git-branch-demo আমাদের প্রজেক্ট। Terminal খুলে টাইপ করুন ঃ

```
mkdir git-branch-demo
cd git-branch-demo  
git init    # initiate empty local repo
echo " # inside master branch " >> main.cpp
```

By default এটা আমাদের মুল ব্রাঞ্চ, এর নাম master. আমরা নতুন ব্রাঞ্চ তোইরই করব এভাবেঃ

```
git checkout -b develop
```

আমরা ব্রাঞ্চ চেক করতে পারি

```
git branch
```

আউটপুট

```
*develop
 master
```

যে ব্রাঞ্চের সামনে \* , আমরা সেই ব্রাঞ্চে অবস্থিত। ১ ব্রাঞ্চ থেকে অন্য়টায় যেতে হয় ঃ

```
git checkout <brunch-name>
# such as

git checkout master # to switch to master

git checkout develop # to switch to develop
```

আমরা ডেভেলপ ব্রাঞ্চ এ যাই । ১টা নতুন ফাইল বানাই ঃ

```
touch branch1.cpp
```

এবার সেখানে নতুন কিছু কোড লিখি। যেমন ঃ

```
\**
*   inside develop branch:   branch1.cpp 
*\ 
#include <stdio.h>
int main()
{
    printf("Hello Branch 1 on develop\n");
    return 0;
}
```

এই ব্রাঞ্চ এর কাজ শেষ হলে কমিট করি ঃ

```
git add .
git status
git commit -m "FC dev 2018-09-15 1"
```

আমাদের আপাতত এই ব্রাঞ্চ এর কাজ শেষ। কাজেই মাস্টের ব্রাঞ্চ এ ফিরে যাই ঃ

```
git checkout master
```

এবার আপনার ফোল্ডারটি ১বার দেখুন। branch1.cpp নাই! ভয়ের কিছু নাই, develop ব্রাঞ্চ এ ফিরে গেলেই আবার চলে আসবে! নিজে চেষ্টা করে দেখুন!

যাহোক, এবার মাস্টার ব্রাঞ্চ এ কিছু কোড লিখি। তবে খেয়াল রাখতে হবে, অন্য ব্রাঞ্চ এ যে ফাইল এ কোড লিখা হইসে ( এক্ষেত্রে branch1.cpp ), সেই নামের ফাইলে কিছু লিখবেন না, অন্যথায় পরবর্তীরে সমস্যা হবে (merge conflict) । এই টিউটোরিয়াল সহজ রাখতে merge conflict আপাতত বাদ। ফিরে আসি কোডে। master ব্রাঞ্চের main.cpp ফাইলে কিছু কোড লিখি ঃ

```
#include <stdio.h>
int main()
{
    printf("Hello master branch\n");
    return 0;
}
```

এবার আগের মতো কমিট করি ঃ

```
git add .
git status
git commit -m "FC master 2018-09-15 1"
```

এবার আমরা merge করব, অর্থাৎ ২টো ব্রাঞ্চকে মিলিয়ে দিব । এজন্য কমান্ড ঃ

```
git merge <branch-name>
```

যে ব্রাঞ্চে merge করব, সেই ব্রাঞ্চ এ যাবো (এক্ষেত্রে master ) এবং যে ব্রাঞ্চকে মারজ করবো তার নাম কমান্ড এ দিবো ( এক্ষেত্রে ) । সুতরাং আমরা master এ গিয়ে টার্মিনালে লিখব ঃ

```
git merge develop
```

তাহলে master ব্রাঞ্চে দিন শেষে আমাদের সম্পূর্ণ প্রোজেক্ট তৈরি হয়ে গেলো, যাতে main.cpp, branch1.cpp এবং তাদের কোড সবকিছু আছে। এরকম একাধিক ব্রাঞ্চ থাকলে সবাইকে মারজ করা যাবে। আমরা github ইতাদি-তেও আমাদের ব্রাঞ্চ রাখতে পারি। ৪ নং অধ্যায় এ রিমোট রিপো বানানোর নিয়ম আছে। সেগুলার পর এই কমান্ড ব্যবহার করুন ঃ

```
git push -u origin master   # to push master branch

git push -u origin develop  # to push develop branch
```

আশা করি ব্রাঞ্চের ব্যপারটা পরিষ্কার হয়ে গেছে!


# গিট লগ

গিট লগ কমান্ডের সাহায্যে গিট রিপোজিটরিতে রাখা সবগুলো কমিটের একটা বিস্তারিত তালিকা দেখা যায়।

## সংক্ষিপ্ত বিবরণ সহ কমিটের তালিকা দেখা

শুধুমাত্র `git log` কমান্ড দিলে আমরা রিপোজিটরির সবগুলো কমিটের একটি বিস্তারিত তালিকা দেখতে পারবো। এখানে আমাদের কমিট হ্যাশ নাম্বার, ব্র্যাঞ্চ, কমিটটির রচয়িতা, তার ইমেইল অ্যাড্রেস, কমিট দেওয়ার তারিখ ও সময় এবং কমিট মেসেজ দেখা যাবে:

![git log](/files/-MBaBAWmFxPpZ6H40H6L)

লিনাক্স-ভিত্তিক অপারেটিং সিস্টেম বা ম্যাকওএসে এই লগ ডিফল্টভাবে Vim টেক্সট এডিটরে ওপেন হবে। এখানে আমরা মাউস ব্যবহার করে অথবা কীবোর্ডের J ও K কী দুটি ব্যবহার করে উপরে-নিচে স্ক্রোল করতে পারি। এখান থেকে বের হতে চাইলে Q প্রেস করবো।

আমরা যদি এগুলোর পাশাপাশি কোন কমিটে কত লাইনের পরিবর্তন হয়েছে দেখতে চাই, তাহলে নিচের কমান্ডটি দেবো।

```bash
git log --stat
```

![git log --stat](/files/-MBaBAWoD0lda_iWPLhr)

এখানে সংখ্যাটি মোট কত লাইনের পরিবর্তন হয়েছে তা নির্দেশ করে। `+` ও `-` চিহ্ন দিয়ে কী পরিমাণ লাইনের সংযোজন-বিয়োজন হয়েছে তার একটা আনুপাতিক ধারণা পাওয়া যায়।

## কমিটের বিস্তারিত বর্ণনা দেখা

আমরা যদি প্রতিটি কমিটের বিস্তারিত বর্ণনা দেখতে চাই, অর্থাৎ কোন কমিটে কী কী ফাইলে কী কী পরিবর্তন হয়েছে দেখতে চাই, তাহলে আমরা `--patch` ফ্ল্যাগটি যোগ করে দেবো। তাহলে কমান্ডটি দাঁড়াচ্ছে,

```bash
git log --patch
```

![git log --patch](/files/-MBaBAWp53MG0OtPGkps)

এখানেও `+` ও `-` চিহ্ন দিয়ে লাইনের সংযোজন-বিয়োজন বোঝানো হয়েছে। এখানে দেখা যাচ্ছে, প্রথম কমিটটিতে লাল লাইনগুলো মুছে ফেলে সেখানে সবুজ লাইনগুলো লেখা হয়েছে। এখানেও `J` ও `K` কী-দুটো ব্যবহার করে উপরে-নিচে স্ক্রোল করা যায় এবং `Q` কী প্রেস করে বেরিয়ে আসা যায়।

কমান্ডটি সংক্ষেপে দেওয়া যেতে পারে এভাবে:

```bash
git log -p
```

## শুধু কমিটের মেসেজগুলো দেখা

আমাদের গিট রিপোজিটরিতে প্রতিটি কমিটেরই একটি মেসেজ থাকে, যেটা দিয়ে আমরা সেই কমিটে কী কাজ করেছি তার একটা ধারণা পাওয়া যায়। আমরা যদি কমিটের বিস্তারিত বর্ণনা না দেখে শুধুমাত্র কমিট মেসেজগুলো এক লাইনে দেখতে চাই, তাহলে নিচের কমান্ডটি ব্যবহার করবো।

```bash
git log --oneline
```

![git log --oneline](/files/-MBaBAWqxYSAIDK0-bqu)

এখানে কমিটগুলোর হ্যাশের সংক্ষিপ্ত রূপ ও কমিট মেসেজের প্রথম লাইনটা দেখা যাচ্ছে। কমিট মেসেজে একাধিক লাইন থাকলে শুধু প্রথম লাইনটাই দেখাবে।

## একটি নির্দিষ্ট কমিটের বিস্তারিত বিবরণ দেখা

আমরা যদি শুধু একটা নির্দিষ্ট কমিটের বিস্তারিত বিবরণ দেখতে চাই, তাহলে `git show (commit hash)` কমান্ড দিয়ে সেটা দেখতে পারি।

ধরা যাক, উপরের উদাহরণে যে কমিটটিতে `Add unit test for Schools Controller` মেসেজ দেওয়া আছে, সেই কমিটের আওতায় কী কী কাজ করা হয়েছিলো, সেটা আমরা দেখতে চাচ্ছি। দেখা যাচ্ছে, ওই কমিটটির হ্যাশ নাম্বার `6bab78a`। তাহলে আমরা কমান্ড লিখতে পারি,

```bash
git show 6bab78a
```

তাহলে আমরা নিচের মত করে ওই কমিটের যাবতীয বিবরণ দেখতে পারবো।

![git show 6bab78a](/files/-MBaBAWrc6xeQpza9orP)

খেয়াল করে দেখবেন, কমিটটির পুরো হ্যাশ নাম্বার হচ্ছে `6bab78a3060e9abe30631a03b75fac043927b8a4`। কিন্তু এখানে কমান্ড দেওয়ার সময় পুরো হ্যাশ নাম্বারটা দেওয়ার প্রয়োজন হয় নি। গিট নিয়ে কাজ করার সময় যে কোন ক্ষেত্রে যদি আপনাকে কোন কমিট নির্দিষ্ট করে বলে দিতে হয়, তাহলে আপনি শুধু সেই কমিট হ্যাশ নাম্বারের প্রথম কয়েকটি ডিজিট বা অক্ষর লিখে দিলেই চলবে, যদি না সেই অক্ষরগুলো অন্য কোন কমিটের হ্যাশ নাম্বারের শুরুতে থাকে।


# গিট চেরি-পিক

কোন গিট রিপোজিটরিতে একাধিক [ব্রাঞ্চ](/8-git-branch) থাকলে এক ব্রাঞ্চের কাজ সহজেই অন্য ব্রাঞ্চে নেওয়া যায় `git cherry-pick` কমান্ড ব্যবহার করে।

ধরা যাক, আমাদের রিপোজিটরিতে `master` ব্রাঞ্চ ছাড়াও আরও দুটো ব্রাঞ্চ আছে: `feature` ও `hotfix`। তিনটি ব্রাঞ্চে আলাদা আলাদাভাবে [লগ](/9-git-log) খুললে এরকম দেখা যাচ্ছে:

**`master` ব্রাঞ্চ:**

![git log on master](/files/-MBaB8uMjt4ncMUMTG6H)

**`feature` ব্রাঞ্চ:**

![git log on feature](/files/-MBaB8uNSPkEUje2zLTq)

**`hotfix` ব্রাঞ্চ:**

![git log on hotfix](/files/-MBaB8uOuZw7qNC-qbbK)

দেখা যাচ্ছে, `master` ব্রাঞ্চে প্রথম কমিটটি দেওয়ার পরই দুটি আলাদা ব্রাঞ্চ খোলা হয়েছে এবং ব্রাঞ্চ দুটিতে পরস্পর থেকে স্বাধীনভাবে কাজ চলছে।

এখন ধরা যাক, আমরা `feature` ব্রাঞ্চে কাজ করছি, আর অন্য কেউ `hotfix` ব্রাঞ্চে কাজ করছেন। `hotfix` ব্রাঞ্চের `Solution to a very specific problem` কমিটে যে কাজটা করা হয়েছে, সেই কাজটি আমাদের বর্তমান ব্রাঞ্চে যোগ করা প্রয়োজন। এর আগের কমিটটি না হলেও চলবে। তাহলে কীভাবে আমরা সেই কমিটটি পেতে পারি?

এটি পাওয়ার উপায় হলো `git cherry-pick`। উক্ত কমিটের হ্যাশ নাম্বার হচ্ছে `ffe3e1f1e516fe73c913796213cfa0a31c60809a`। তাহলে আমরা আমাদের `feature` ব্রাঞ্চে থাকা অবস্থায় নিচের কমান্ডটি দিতে পারি:

```bash
git cherry-pick ffe3e1f
```

তাহলেই `hotfix` ব্রাঞ্চ থেকে ওই একটি কমিট আমাদের `feature` ব্রাঞ্চে চলে আসবে। এখন যদি আমরা `git log` কমান্ড দেই, তাহলে দেখতে পাবো,

![git log on feature after cherry-pick](/files/-MBaB8uPuDRqMo0bGdhm)

দেখা যাচ্ছে, `hotfix` ব্রাঞ্চ থেকে শুধুমাত্র ওই একটি কমিট `feature` ব্রাঞ্চে যোগ হয়েছে এবং `feature` ব্রাঞ্চে করা আগের কমিটগুলো আগের মতই রয়ে গেছে।


