গিটে, আমি কীভাবে একই প্রতিশ্রুতিতে কোনও ফাইলের বর্তমান কমিট হ্যাশ লিখতে পারি


131

আমি এখানে গিট হুক দিয়ে অভিনব জিনিস করার চেষ্টা করছি, তবে কীভাবে এটি করা যায় তা আমি জানি না (বা এটি সম্ভব হলে)।

আমার যা করা দরকার তা হ'ল: প্রতিটি প্রতিশ্রুতিতে আমি এর হ্যাশ নিতে চাই এবং তারপরে এই হ্যাশটির সাথে প্রতিশ্রুতিতে একটি ফাইল আপডেট করতে চাই।

কোন ধারনা?


12
মূলত আমার একটি ওয়েব অ্যাপ্লিকেশন রয়েছে এবং আমি সেই অ্যাপ্লিকেশনটির একটি ইনস্টলড সংস্করণটির সাথে সংগত করতে চাই যে সেই সংস্করণের সাথে সম্পর্কিত is আমার প্রাথমিক ধারণাটি ছিল কমিট হ্যাশ সহ এক প্রকারের সম্পর্কে html ফাইল আপডেট করা। তবে গিটের অবজেক্টস মডেল অধ্যয়ন করার পরে আমি বুঝতে পেরেছিলাম যে এটি এক ধরণের অসম্ভব = /
ফিলিপ কামাকুড়া

29
এটি একটি খুব ব্যবহারিক সমস্যা। আমিও এর মধ্যে দৌড়ে গেলাম!
লি দং

7
আমার হিসাবে, আমি আমার প্রোগ্রামটি লগগুলিতে এই জাতীয় বার্তা লিখতে চাই: "মাইপ্রোগ শুরু, v.56c6bb2"। এইভাবে, যদি কেউ একটি বাগ ফাইল করে এবং আমাকে লগ ফাইলগুলি প্রেরণ করে তবে আমি জানতে পারি যে আমার প্রোগ্রামটির ঠিক কোন সংস্করণ চলছে।
এডওয়ার্ড ফালক

5
@ জেফ্রোমি, প্রকৃত ব্যবহারের ঘটনাটি আসলে খুব সাধারণ, এবং খুব সহজেই নবজাতককে আঘাত করে। বেসলাইন করা ফাইলগুলিতে একরকম "সংক্রামিত" আসল সংস্করণ থাকা একটি মৌলিক প্রয়োজন এবং এটি কেন ভুল ধারণা হতে পারে তা স্পষ্টতই দূরে, যেমন ম্যানুয়াল রিভিশন কন্ট্রোল হ্যাকগুলির সাথে এটি আপনার একমাত্র বিকল্প। (নতুনদের মনে রাখবেন।) এর সাথে যোগ করুন যে অনেকগুলি প্রকল্পের কোনও বিল্ড / ইনস্টলেশন / স্থাপনার পদক্ষেপের কোনওরকমই নেই যা সংস্করণটিকে লাইভ ফাইলগুলিতে দখল করতে এবং স্ট্যাম্প করতে পারে। নির্বিশেষে, প্রাক-প্রতিশ্রুতির পরিবর্তে, চেকআউট পোস্ট হুক এমনকি সেই ক্ষেত্রেও সহায়তা করতে পারে।
জেড

এটা অসম্ভব! আপনি SHA-1 হ্যাশ অ্যালগরিদম কপর্দকশূন্য আপনি এটা করতে পারেন তাহলে ... ericsink.com/vcbe/html/cryptographic_hashes.html
betontalpfa

উত্তর:


82

আমি আপনার মনে যেমন কিছু আছে তার অনুরূপ কিছু করার পরামর্শ দিচ্ছি: বিল্ড / ইন্সটলেশন / স্থাপনার প্রক্রিয়াটির অংশ হিসাবে জেনারেট হওয়া, একটি অচিহ্নযুক্ত ফাইলের মধ্যে SHA1 স্থাপন । এটি করা স্পষ্টতই সহজ ( git rev-parse HEAD > filenameবা সম্ভবত git describe [--tags] > filename), এবং এটি গিটের ট্র্যাকিংয়ের চেয়ে পৃথক কোনও ফাইল শেষ করার মতো পাগল কিছু করা এড়িয়ে যায়।

আপনার কোডটি তখন এই ফাইলটিকে রেফারেন্স করতে পারে যখন সংস্করণ নম্বর প্রয়োজন হয় বা একটি বিল্ড প্রক্রিয়া চূড়ান্ত পণ্যটির সাথে তথ্য অন্তর্ভুক্ত করতে পারে। পরেরটি আসলে গিটটি কীভাবে তার সংস্করণ নম্বরগুলি অর্জন করে - বিল্ড প্রক্রিয়াটি রেপোর বাইরে সংস্করণ নম্বরটি ধরে ফেলে এবং তারপরে এক্সিকিউটেবলের মধ্যে তৈরি করে।


3
কেউ কীভাবে এই পদক্ষেপে আরও ধাপে ধাপে ব্যাখ্যা করতে পারে? বা কমপক্ষে সঠিক দিকের একটি ধাক্কা?
জোয়েল ওয়ারশাম

1
@ জোয়েল কীভাবে করবেন? আমি একটি ফাইলের মধ্যে হ্যাশ কীভাবে রাখব তা উল্লেখ করেছি; বাকি সম্ভবত আপনার বিল্ড প্রক্রিয়া সম্পর্কে কিছু? আপনি যদি সেই অংশটি সম্পর্কে জিজ্ঞাসা করার চেষ্টা করছেন তবে হয়ত একটি নতুন প্রশ্ন।
ক্যাসাবেল

1
আমার ক্ষেত্রে, আমি আমার মেকফাইলে একটি বিধি যুক্ত করেছি যা প্রতিটি বিল্ডে একটি "gitversion.h" ফাইল উত্পন্ন করে। স্ট্যাকওভারফ্লো.com
এডওয়ার্ড ফ্যাল্ক

1
আপনি "গিট-চেকআউট" হুক দিয়ে এটি স্বয়ংক্রিয় করতে সক্ষম হতে পারেন। সমস্যা হুকগুলি ম্যানুয়ালি ইনস্টল করতে হবে।
এডওয়ার্ড ফালক

14

বর্তমান কমিটের হ্যাশটি লেখা অসম্ভব: আপনি যদি ভবিষ্যতের প্রতিশ্রুতি হ্যাশটির প্রাক-গণনা করতে পরিচালনা করেন - আপনি কোনও ফাইল সংশোধন করার সাথে সাথে এটি পরিবর্তন হবে।

তবে, এখানে তিনটি বিকল্প রয়েছে:

  1. 'কমিট আইডি' বর্ধিত করতে এবং এটি কোথাও অন্তর্ভুক্ত করতে একটি স্ক্রিপ্ট ব্যবহার করুন। অরুপ
  2. .Gitignore ফাইলটিতে আপনি হ্যাশ সংরক্ষণ করতে যাচ্ছেন। খুব সহজ নয়
  3. ইন pre-commit, পূর্ববর্তী কমিট হ্যাশ সংরক্ষণ করুন :) আপনি 99.99% ক্ষেত্রে কমিটগুলি সংশোধন / সন্নিবেশ করান না, সুতরাং এই কাজ করবে work সবচেয়ে খারাপ ক্ষেত্রে আপনি এখনও উত্সের সংশোধন সনাক্ত করতে পারেন।

আমি একটি হুক স্ক্রিপ্টে কাজ করছি, এটি 'এটি শেষ হয়ে গেলে' এখানে পোস্ট করব, তবে এখনও - ডিউক নোকেম চিরকালের জন্য প্রকাশিত হওয়ার আগে :))

আপডেট : এর জন্য কোড .git/hooks/pre-commit:

#!/usr/bin/env bash
set -e

#=== 'prev-commit' solution by o_O Tync
#commit_hash=$(git rev-parse --verify HEAD)
commit=$(git log -1 --pretty="%H%n%ci") # hash \n date
commit_hash=$(echo "$commit" | head -1)
commit_date=$(echo "$commit" | head -2 | tail -1) # 2010-12-28 05:16:23 +0300

branch_name=$(git symbolic-ref -q HEAD) # http://stackoverflow.com/questions/1593051/#1593487
branch_name=${branch_name##refs/heads/}
branch_name=${branch_name:-HEAD} # 'HEAD' indicates detached HEAD situation

# Write it
echo -e "prev_commit='$commit_hash'\ndate='$commit_date'\nbranch='$branch'\n" > gitcommit.py

এখন আমাদের কেবলমাত্র একটি সরঞ্জাম প্রয়োজন যা জোড়াটিকে prev_commit,branchএকটি সত্যিকারের কমিট হ্যাশে রূপান্তরিত করে :)

আমি জানি না যে এই পদ্ধতির মাধ্যমে মার্জিং কমিটগুলি পৃথক করে বলতে পারে কিনা। শীঘ্রই এটি পরীক্ষা করে দেখা হবে


13

কেউ আমাকে পরিচয় সম্পর্কিত "ম্যান গিটটিট্রিবিউটস" বিভাগের দিকে ইঙ্গিত করেছেন, যা এতে রয়েছে:

ident

অ্যাট্রিবিউট পরিচয়টি যখন কোনও পাথের জন্য সেট করা হয়, তখন গিট the আইডির সাথে ব্লব অবজেক্টে $ আইডি la প্রতিস্থাপন করে, তারপরে 40-অক্ষরের হেক্সাডেসিমাল ব্লব অবজেক্টের নাম, তারপরে ডলার চিহ্ন-পরে চেকআউট হয় $ T আইডির সাথে শুরু হওয়া এবং ওয়ার্ট্রি ফাইলটিতে with দিয়ে শেষ হওয়া কোনও বাইট ক্রম চেক ইন করার পরে replaced আইডি $ দিয়ে প্রতিস্থাপন করা হবে।

আপনি যদি এটির বিষয়ে চিন্তা করেন তবে এটি সিভিএস, সাবভার্সন ইত্যাদিও করে। আপনি যদি সংগ্রহস্থলের দিকে তাকান, আপনি দেখতে পাবেন যে ভান্ডারটিতে থাকা ফাইলটিতে সর্বদা থাকে, উদাহরণস্বরূপ, $ আইডি $ $ এটি কখনই এর সম্প্রসারণ ধারণ করে না। এটি কেবলমাত্র চেকআউটে রয়েছে যে পাঠ্যটি প্রসারিত।


8
identফাইলটি হ্যাশ হ'ল, প্রতিশ্রুতি দেওয়ার তাড়াতাড়ি নয়। Git-scm.com/book/en/… থেকে : "তবে, ফলাফলটি সীমিত ব্যবহারের। আপনি যদি সিভিএস বা সাবভার্সনে কীওয়ার্ডের বিকল্প ব্যবহার করেন তবে আপনি একটি ডেটস্ট্যাম্প অন্তর্ভুক্ত করতে পারেন - এসএইচএ সমস্ত সহায়ক নয়, কারণ এটি মোটামুটি এলোমেলো এবং আপনি বলতে পারবেন না যে কোনও SHA অন্যের চেয়ে বয়স্ক বা নতুন "" filterকাজ করে, তবে এটি একটি ফাইলের (এবং বাইরে) প্রতিশ্রুতিবদ্ধ তথ্য পেতে পারে।
জ্যাচ ইয়ং

11

গিটাট্রিবিউটগুলিতেfilter বৈশিষ্ট্যটি ব্যবহার করে এটি অর্জন করা যেতে পারে । আপনাকে একটি কমান্ড সরবরাহ করতে হবে যা প্রতিশ্রুতি আইডি সন্নিবেশ করায় এবং এটি সরিয়ে দেয় এমন একটি কমান্ড, যেমন এটি সন্নিবেশ করা ফাইলটি কেবল কমিট আইডির কারণে পরিবর্তিত হবে না।smudgeclean

সুতরাং, প্রতিশ্রুতিবদ্ধ আইডি কখনই ফাইলের ব্লবে সংরক্ষণ করা হয় না; এটি আপনার কাজের অনুলিপিটিতে কেবল প্রসারিত হয়েছে ed (প্রকৃতপক্ষে ব্লবটিতে কমিট আইডি tingোকানো একটি অসীম পুনরাবৃত্তির কাজ হয়ে যাবে ☺) যে কেউ এই গাছটিকে ক্লোন করেন তার নিজের জন্য বৈশিষ্ট্যগুলি সেট আপ করতে হবে।


7
অসম্ভব টাস্ক, পুনরাবৃত্তির কাজ নয়। কমিট হ্যাশ ট্রি হ্যাশের উপর নির্ভর করে যা ফাইল হ্যাশের উপর নির্ভর করে যা ফাইলের সামগ্রীর উপর নির্ভর করে। আপনাকে স্ব-ধারাবাহিকতা পেতে হবে। আপনি SHA-1 হ্যাশের জন্য এক ধরণের [সাধারণীকৃত] নির্দিষ্ট পয়েন্ট পাবেন না যদি না ।
জাকুব নরবস্কি

1
@ জাকুব, গিটের মধ্যে এমন কোনও কৌশল আছে যা ট্র্যাকযুক্ত ফাইল তৈরি করতে দেয় যা ফলাফলগুলি হ্যাশ সংশোধন করে না? এর হ্যাশটিকে ওভাররাইড করার কিছু উপায় হতে পারে। এটি সমাধান হয়ে যাবে :)
কলিপ্টো

@o_O টিঙ্ক: সম্ভব নয়। পরিবর্তিত ফাইলের অর্থ পরিবর্তিত হ্যাশ (কোনও ফাইলের) - এটি নকশা দ্বারা এবং একটি হ্যাশ ফাংশন সংজ্ঞা দ্বারা।
জাকুব নরবস্কি

2
এটি একটি দুর্দান্ত সমাধান, তবে মনে রাখবেন যে এর মধ্যে হুকগুলি অন্তর্ভুক্ত রয়েছে যা যখনই আপনি কোনও সংগ্রহস্থল ক্লোন করেন তখন ম্যানুয়ালি ইনস্টল করতে হয়।
এডওয়ার্ড ফালক

7

কমিট বক্সের বাইরে ভাবুন!

ফাইল হুক / পোস্ট-চেকআউট এ এটি পপ করুন

#!/bin/sh
git describe --all --long > config/git-commit-version.txt

সংস্করণটি আপনি এটি যে কোনও জায়গায় ব্যবহার করবেন।


3

আমি মনে করি না আপনি আসলে এটি করতে চান, কারণ যখন কমিটের কোনও ফাইল পরিবর্তন হয়, তখন কমিটের হ্যাশও বদলে যায়।


1

গিট ইন্টার্নালগুলি ব্যবহার করে এটি কেন চ্যালেঞ্জিং সমস্যা তা আমাকে এক্সপ্লোর করতে দিন। আপনি এর মাধ্যমে বর্তমান কমিটের sha1 পেতে পারেন

#!/bin/bash
commit=$(git cat-file commit HEAD) #
sha1=($((printf "commit %s\0" $(echo "$commit" | wc -c); echo "$commit") | sha1sum))
echo ${sha1[0]}

মূলত আপনি ফিরে আসা বার্তায় একটি sha1 চেকসাম চালান git cat-file commit HEAD। আপনি যখন এই বার্তাটি পরীক্ষা করেন তখন দুটি জিনিস তত্ক্ষণাত্ সমস্যা হিসাবে ঝাঁপিয়ে পড়ে। একটি গাছের শা 1 এবং দ্বিতীয়টি কমিট সময় time

এখন কমিটের সময়টি সহজেই বার্তাটি পরিবর্তন করে এবং নির্দিষ্ট সময়ে প্রতিশ্রুতিবদ্ধ হতে কমিটিকে সময় নির্ধারণ করতে বা সময় নির্ধারণ করতে কত সময় লাগে তা অনুমান করে সহজেই যত্ন নেওয়া হয়। আসল সমস্যাটি হ'ল ট্রি শ 1, যা থেকে আপনি তা পেতে পারেন git ls-tree $(git write-tree) | git mktree। মূলত আপনি এলএস-ট্রি থেকে প্রাপ্ত বার্তায় একটি sha1 চেকসাম করছেন যা সমস্ত ফাইল এবং তাদের sha1 চেকসামের একটি তালিকা।

সুতরাং আপনার কমিট শ 1 চেকসাম আপনার গাছের শ 1 চেকসামের উপর নির্ভর করে, যা সরাসরি ফাইল শ 1 চেকসামের উপর নির্ভর করে যা বৃত্তটি সম্পূর্ণ করে এবং কমিট শ 1 এর উপর নির্ভর করে। সুতরাং আপনার নিজের কাছে আমার কাছে উপলব্ধ প্রযুক্তিগুলির সাথে একটি বিজ্ঞপ্তি সমস্যা রয়েছে।

সঙ্গে কম নিরাপদ চেকসাম , এটা সম্ভব দেখানো হয়েছে পাশব বল মাধ্যমে ফাইল নিজেই মধ্যে ফাইলের চেকসাম লিখতে; তবে, sha1 দিয়ে সেই কাজটি সম্পন্ন করে এমন কোনও কাজ আমি জানি না। এটি অসম্ভব নয়, তবে আমাদের বর্তমান বোঝাপড়ার সাথে অসম্ভবের পরেও (তবে কে জানেন যে কয়েক বছরের মধ্যে এটি ক্ষুদ্র হবে)। যাইহোক, এটি এখনও জোর করা শক্ততর কারণ যেহেতু আপনাকে ফাইলের মধ্যে একটি (বৃক্ষ) চেকসামের (বৃক্ষ) চেকসামের (কমিট) চেকসামটি লিখতে হবে।


এমন কি কোনও উপায় আছে যে কেউ ফাইলগুলি প্রতিশ্রুতিবদ্ধ করতে পারে, তারপরে একটি চেকআউট করবে এবং প্রতিটি উত্স কোড ফাইলের শুরুতে একটি মন্তব্য হিসাবে সর্বশেষ প্রতিশ্রুতিবদ্ধ হ্যাশ রাখবে? তারপরে কি তা তৈরি করে চালাবেন?
জন ওয়াটেন
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.