তুলনা

git fetch ও git pull: পার্থক্য কী এবং কোনটি বেছে নেবেন

হালনাগাদ: · Skillaria.Top

git fetch শুধু সার্ভার থেকে নতুন কমিট নামায় এবং origin/main-এর মতো রিমোট ব্রাঞ্চের চিহ্ন হালনাগাদ করে, আপনার ফাইল ও ব্রাঞ্চে হাত দেয় না। git pull একই কাজ করে এবং তারপর সঙ্গে সঙ্গে নামানো পরিবর্তন বর্তমান ব্রাঞ্চে merge বা rebase দিয়ে মেশায়। Fetch সবসময় নিরাপদ, pull তখনই সুবিধাজনক যখন নতুন পরিবর্তন সঙ্গে সঙ্গে নিতে প্রস্তুত।

সংক্ষিপ্ত উত্তর

git fetch সার্ভার থেকে নতুন কমিট নামায় এবং রিমোট ব্রাঞ্চের চিহ্নগুলো (origin/main, origin/feature-x) হালনাগাদ করে, কিন্তু আপনার বর্তমান ব্রাঞ্চ বা ওয়ার্কিং ফোল্ডারের ফাইল বদলায় না। git pull হলো git fetch এবং তার সঙ্গে সঙ্গে নামানো পরিবর্তন বর্তমান ব্রাঞ্চের সঙ্গে merge (ডিফল্ট) বা rebase দিয়ে মেশানো।

তাই ব্যবহারিক নিয়ম: fetch যেকোনো সময় চালানো যায়, কিছুই ভাঙে না। pull আপনার ব্রাঞ্চ বদলায় এবং কনফ্লিক্টে শেষ হতে পারে, তাই এটি চালান পরিষ্কার ওয়ার্কিং ফোল্ডারে এবং কী আসছে তা জেনে।

রিমোট ব্রাঞ্চ কোথায় থাকে

পার্থক্যটি বুঝতে জানা দরকার, লোকাল রিপোজিটরিতে দুই ধরনের ব্রাঞ্চ আছে। লোকাল ব্রাঞ্চ — main, feature-x — আপনার কমিটে এগোয়। রিমোট-ট্র্যাকিং ব্রাঞ্চ — origin/main — হলো "শেষ সিঙ্কের সময় সার্ভার এমন ছিল" এর বুকমার্ক। এগুলো নিজে হাতে সরানো যায় না, শুধু সার্ভারের সঙ্গে যোগাযোগে (fetch, pull ও push) হালনাগাদ হয়।

git branch -a
* main
  remotes/origin/HEAD -> origin/main
  remotes/origin/main
  remotes/origin/feature-x

git status আপনার ব্রাঞ্চকে আসলে origin/main বুকমার্কের সঙ্গে তুলনা করে, জীবন্ত সার্ভারের সঙ্গে নয়। তাই "Your branch is up to date with 'origin/main'" বার্তা মিথ্যা হতে পারে: অনেকক্ষণ fetch না হলে Git সহকর্মীদের নতুন কমিট জানে না।

git fetch কী করে

$ git fetch
remote: Enumerating objects: 7, done.
remote: Counting objects: 100% (7/7), done.
Unpacking objects: 100% (4/4), done.
From github.com:team/project
   3f2a1c9..8b7d4e2  main       -> origin/main

শেষ লাইনটি মূল কথা বলে: origin/main সরেছে 3f2a1c9 থেকে 8b7d4e2-এ। আপনার main নিজের জায়গায় আছে। এখন নিশ্চিন্তে দেখা যায় কী এসেছে:

git status                       # Your branch is behind 'origin/main' by 2 commits
git log main..origin/main --oneline   # যে কমিট আপনার কাছে নেই
git diff main origin/main        # ফাইলে কী বদলাবে

fetch-এর কয়েকটি কার্যকর রূপ:

  • git fetch --all — সব remote থেকে নিয়ে আসা (ফর্কে origin ও upstream থাকলে কাজে লাগে);
  • git fetch --prune (-p) — সার্ভারে আর না থাকা রিমোট বুকমার্ক মুছে ফেলা;
  • git fetch origin main — শুধু একটি ব্রাঞ্চ;
  • git fetch --tags — সব ট্যাগও নামানো।

প্রুনিং সবসময় চালু রাখতে একবার সেট করুন: git config --global fetch.prune true।

git pull কী করে

git pull পরপর দুটি ধাপ চালায়। প্রথমে বর্তমান ব্রাঞ্চের upstream-এর জন্য fetch, তারপর origin/<ব্রাঞ্চ>-কে আপনার ব্রাঞ্চের সঙ্গে মেশানো। আক্ষরিক অর্থে এটি এর সমতুল্য:

git fetch origin
git merge origin/main      # বা pull --rebase হলে git rebase origin/main

মেশানোর ফল নির্ভর করে ইতিহাস কীভাবে আলাদা হয়েছে তার ওপর:

  • আপনার নতুন কমিট নেই — fast-forward হয়, ব্রাঞ্চ শুধু সামনে সরে;
  • আপনার আর সার্ভারের উভয়ের নতুন কমিট আছে — merge-এ একটি merge কমিট হয়, rebase-এ আপনার কমিটগুলো সার্ভারের কমিটের ওপর আবার সাজানো হয়;
  • দুই দিকে একই লাইন বদলেছে — কনফ্লিক্ট, যা হাতে মেটাতে হয়।

git fetch ও git pull তুলনা

git fetchgit pull
কমিট নামায়হ্যাঁহ্যাঁ
origin/* হালনাগাদ করেহ্যাঁহ্যাঁ
বর্তমান ব্রাঞ্চ বদলায়নাহ্যাঁ
ওয়ার্কিং ফোল্ডারের ফাইল বদলায়নাহ্যাঁ
কনফ্লিক্ট হতে পারেনাহ্যাঁ
পরিষ্কার ওয়ার্কিং ফোল্ডার লাগেনাকাম্য
অন্য ব্রাঞ্চ প্রভাবিত হয়সব অনুসরণকারী বুকমার্ক হালনাগাদশুধু বর্তমানে মেশায়
কখন ব্যবহার করবেনকী বদলেছে দেখতে; rebase-এর আগে; স্ক্রিপ্টেনিজের ব্রাঞ্চে দ্রুত সার্ভারের সঙ্গে মেলাতে

git pull: merge না rebase

Git 2.27 থেকে ইতিহাস ভিন্ন হলে স্পষ্ট সেটিং ছাড়া pull সতর্ক করে, আর নতুন সংস্করণে নীরবে merge না করে থেমে যায় এই বার্তায়: "Need to specify how to reconcile divergent branches"। Git একবার পছন্দ জানতে চায়:

git config --global pull.rebase false   # merge (আগের ডিফল্ট আচরণ)
git config --global pull.rebase true    # rebase
git config --global pull.ff only        # শুধু fast-forward, নইলে প্রত্যাখ্যান

Merge ইতিহাস যেমন আছে তেমন রাখে এবং "Merge branch 'main' of github.com:..." কমিট যোগ করে। স্থানীয় কমিটসহ ব্রাঞ্চে প্রতিদিন pull করলে ইতিহাসে এমন প্রযুক্তিগত মেশানোর স্তূপ জমে।

Rebase আপনার অপ্রকাশিত কমিটগুলো নতুন সার্ভার কমিটের ওপর সাজায়। ইতিহাস সরলরেখায় থাকে, আর কনফ্লিক্ট একসঙ্গে একটি কমিট ধরে মেটানো হয়। অপ্রকাশিত স্থানীয় কমিটের জন্য এটি সাধারণত সেরা পছন্দ। শুধু যেসব কমিট ইতিমধ্যে পাঠানো হয়েছে এবং অন্যরা তার ওপর কাজ করছে, সেখানে rebase বিপজ্জনক।

ff only সবচেয়ে কঠোর: pull তখনই চলে যখন আপনার নিজের কমিট নেই। ইতিহাস ভিন্ন হলে সিদ্ধান্তটি আপনাকে স্পষ্টভাবে নিতে হয়। অনেক অভিজ্ঞ ডেভেলপার মূল ব্রাঞ্চের জন্য এটি সেট করেন।

রিপোজিটরির ওয়ার্কিং ফোল্ডারে অকমিট পরিবর্তন থাকলে এবং এখনই pull দরকার, তখন git pull --rebase --autostash কাজে লাগে: Git পরিবর্তনগুলো সরিয়ে রাখে, rebase করে, তারপর আবার ফিরিয়ে দেয়।

সাধারণ কৌশল: fetch, দেখা, তারপর মেশানো

"আগে fetch" পদ্ধতিতে আপনার ব্রাঞ্চে কী ঢুকছে তার ওপর নিয়ন্ত্রণ থাকে। pull request পাঠানোর আগে এবং দীর্ঘ বিরতির পর এটি বিশেষভাবে কাজে লাগে।

git fetch
git log --oneline --graph HEAD origin/main   # ব্রাঞ্চগুলো কীভাবে আলাদা হয়েছে
git rebase origin/main                       # বা git merge origin/main
git push

আরেকটি সাধারণ পরিস্থিতি: নিজের feature ব্রাঞ্চকে সর্বশেষ main দিয়ে হালনাগাদ করা, তাতে না গিয়েই:

git switch feature-x
git fetch
git rebase origin/main

এখানে pull উপযুক্ত নয়: feature-ব্রাঞ্চে git pull নিজের upstream (origin/feature-x) থেকে টানে, মূল ব্রাঞ্চ থেকে নয়। অবশ্য git pull --rebase origin main লেখাও যায়, তবে fetch-ওয়ালা উপায়টি স্পষ্টতর।

সার্ভারের সঙ্গে সিঙ্ক: ব্রাঞ্চ হালনাগাদ রাখা

"git sync" বললে সাধারণত বোঝানো হয় একটি চক্র: "অন্যের কাজ নাও, নিজের কাজ পাঠাও"। বিশুদ্ধ Git-এ আলাদা sync কমান্ড নেই (IDE ও GUI ক্লায়েন্টের Sync বোতাম ভেতরে pull এবং তারপর push করে)। হাতে নির্ভরযোগ্য চক্রটি এমন:

  1. git status — নিশ্চিত হোন সবকিছু কমিট বা git stash করা আছে;
  2. git pull --rebase — পরিবর্তন নিন এবং নিজের কমিট ওপরে সাজান;
  3. কনফ্লিক্ট থাকলে মেটান: ফাইল ঠিক করুন, git add, git rebase --continue;
  4. টেস্ট চালান;
  5. git push।

মূল রিপোজিটরির সঙ্গে ফর্ক মেলাতে:

git remote add upstream https://github.com/original/project.git
git fetch upstream
git switch main
git merge --ff-only upstream/main
git push origin main

git pull-এর সাধারণ সমস্যা

Your local changes would be overwritten by merge

pull এমন ফাইল বদলাতে চায়, যা আপনি সম্পাদনা করছেন কিন্তু কমিট করেননি। বিকল্প: কমিট করুন, সরিয়ে রাখুন (git stash, তারপর pull এবং git stash pop), অথবা --autostash ব্যবহার করুন। pull-এর জন্য পরিবর্তন মুছে ফেলার দরকার নেই।

pull-এর পর কনফ্লিক্ট

Git থামবে এবং git status-এ কনফ্লিক্টের ফাইল দেখাবে। ফাইল খুলুন, <<<<<<< ও >>>>>>> মার্কারের মাঝে সঠিক অংশটি রাখুন, তারপর git add এবং git commit (merge-এর ক্ষেত্রে) বা git rebase --continue (rebase-এর ক্ষেত্রে)। মত বদলালে git merge --abort বা git rebase --abort pull-এর আগের অবস্থায় ফেরায়।

There is no tracking information for the current branch

ব্রাঞ্চের upstream নেই, তাই Git জানে না কোথা থেকে টানতে হবে। স্পষ্ট বলুন: git pull origin main, অথবা একবার সংযোগ সেট করুন: git branch --set-upstream-to=origin/main।

refusing to merge unrelated histories

লোকাল ও রিমোট রিপোজিটরি আলাদাভাবে তৈরি, যেমন সার্ভারে তৈরির সময় README যোগ করা হয়েছিল। নিশ্চিত হলে মেশাতে: git pull origin main --allow-unrelated-histories।

ভুল pull থেকে ফেরা

pull-এর merge শেষ হয়ে গেছে এবং ফলাফল পছন্দ না হলে ব্রাঞ্চ আগের অবস্থায় ফেরান: git reset --hard ORIG_HEAD। এটি অকমিট পরিবর্তন মুছে দেয়, তাই আগে git status দেখে নিন। শেষ উপায় হিসেবে আগের অবস্থান git reflog-এ পাওয়া যায়।

কোনটি বেছে নেবেন

  • কিছু না বদলে জানতে চান কী নতুন — git fetch।
  • নিজের ব্রাঞ্চে শুধু সার্ভারের সঙ্গে মেলাতে চান — git pull --rebase (বা pull.rebase true সেট করা থাকলে pull)।
  • মূল ব্রাঞ্চ হালনাগাদ করতে চান, নিজের কমিট ছাড়া — git pull --ff-only।
  • feature-ব্রাঞ্চে main মেশাতে চান — git fetch, তারপর git rebase origin/main বা git merge origin/main।
  • স্ক্রিপ্ট বা CI লিখছেন — fetch ও স্পষ্ট কমান্ড, pull নয়।

কমিট গ্রাফে এটি কেমন দেখায়

ধরুন আপনি ও সহকর্মী কমিট C থেকে শুরু করেছেন। আপনি স্থানীয়ভাবে D কমিট করেছেন, আর সহকর্মী সার্ভারে E পাঠিয়েছেন। git fetch-এর পর আপনার রিপোজিটরি দুটি ধারাই জানে: main নির্দেশ করে D-কে, origin/main নির্দেশ করে E-কে, এবং তাদের সাধারণ পূর্বপুরুষ C।

          D   <- main (HEAD)
         /
A---B---C
         \
          E   <- origin/main

এরপর মেশানোর পদ্ধতিই ঠিক করে ফল কী হবে। git merge origin/main দুই প্যারেন্ট D ও E-বিশিষ্ট একটি M কমিট বানায়। git rebase origin/main D-কে E-এর ওপর নতুন কমিট D' হিসেবে কপি করে, ভিন্ন হ্যাশসহ, এবং ইতিহাস হয় সরল রেখা। git pull এই একই ধাপগুলো স্বয়ংক্রিয়ভাবে চালায়, মাঝখানে থামে না। আর এই থামার সুযোগটিই, অর্থাৎ মেশানোর আগে গ্রাফ দেখার সুবিধা, আলাদা fetch-এর আসল মূল্য।

IDE-তে fetch ও pull

VS Code, IntelliJ IDEA ও অন্যান্য এডিটরে বোতামের নাম আলাদা, কিন্তু নিচে একই কমান্ড। "Fetch" মানে git fetch, "Pull" বা "Update Project" মানে সেটিংসে বেছে নেওয়া কৌশলসহ pull (merge বা rebase), "Sync Changes" মানে pull এবং তারপর push। শেয়ার্ড ব্রাঞ্চে Sync চাপার আগে জানা ভালো কোন কৌশল বাছা আছে, নইলে ইতিহাসে অপ্রত্যাশিত merge কমিট আসতে পারে। অনেক IDE পটভূমিতে নিয়মিত fetch করে, তাই স্ট্যাটাস বারের "ইনকামিং কমিট" সংখ্যা সাধারণত হালনাগাদ থাকে।

সারসংক্ষেপ

git fetch সার্ভার সম্পর্কে আপনার জ্ঞান হালনাগাদ করে, git pull সেই জ্ঞান বর্তমান ব্রাঞ্চে প্রয়োগও করে। Fetch যেকোনো সময় নিরাপদ, pull সুবিধাজনক কিন্তু ব্রাঞ্চ বদলায় এবং কনফ্লিক্ট আনতে পারে, তাই একবার কৌশল ঠিক করুন এবং ওয়ার্কিং ফোল্ডার পরিষ্কার রাখুন। push, pull, fetch, রিমোট ও GitHub-এর সঙ্গে কাজ Git কোর্সে বাস্তব অনুশীলনে শেখানো হয়।

সাধারণ প্রশ্ন

git pull-এর আগে কি git fetch লাগে?

না, pull নিজেই প্রথম ধাপে fetch চালায়। আলাদা fetch দরকার হয়, যখন আগে পরিবর্তন দেখতে চান, তারপর ঠিক করতে চান কীভাবে মেশাবেন।

git fetch কি আমার পরিবর্তন মুছে দিতে পারে?

না। fetch শুধু origin/main-এর মতো রিমোট চিহ্ন বদলায়, লোকাল ব্রাঞ্চ, ইনডেক্স ও ওয়ার্কিং ফোল্ডারে হাত দেয় না।

git pull কি সব ব্রাঞ্চ হালনাগাদ করে?

না, pull শুধু বর্তমান ব্রাঞ্চে মেশায়। অন্য ব্রাঞ্চের origin/* চিহ্ন fetch-এ হালনাগাদ হয়, কিন্তু লোকাল ব্রাঞ্চগুলো নিজের জায়গায় থাকে।

কত ঘন ঘন git fetch করা উচিত?

কাজ শুরুর আগে, pull request পাঠানোর আগে এবং push-এর আগে। অনেক IDE পটভূমিতে নিজে fetch করে, এটি নিরাপদ।

FETCH_HEAD কী?

একটি সহায়ক রেফারেন্স, যেখানে fetch সর্বশেষ নামানো কমিট লেখে। যেমন git fetch origin main-এর পর git merge FETCH_HEAD চালানো যায়।

ভিডিওতে বিষয়টি শিখুন

“শূন্য থেকে আত্মবিশ্বাসী ডেভেলপার পর্যন্ত গিট” কোর্সে বিষয়টি অনুশীলনসহ বিস্তারিত শেখানো হয়েছে।

কোর্সে যান