ফাইলের একটি সংস্করণ ব্যক্তিগত রাখার জন্য গিথুব কৌশল


11

আমি একজন প্রভাষক যা শিক্ষার্থীদের কোডিংয়ের সমস্যা লিখছি। আমি যা করতে চাই তা হ'ল শিক্ষার্থীদের প্লে-হোল্ডারদের সাথে বয়লারপ্লিট কোডটি শিক্ষার্থীদের যে কাজগুলি সম্পন্ন করতে হবে তার জন্য give এটি ক্লোন করার জন্য আমি শিক্ষার্থীদের একটি ব্যক্তিগত গিথুব রেপোতে অ্যাক্সেস দেব give

তবে, আমি কোডবেসের একটি সংস্করণও চাই, নমুনা সমাধান সহ সম্পূর্ণ। স্পষ্টতই আমি চাই না যে শিক্ষার্থীরা সমাধানটিতে অ্যাক্সেস পান (অ্যাসাইনমেন্টটি শেষ না হওয়া পর্যন্ত)।

আমি শাখা সম্পর্কে চিন্তাভাবনা করেছি, কিন্তু আফাইক, আমি একটি শাখা ব্যক্তিগত রাখতে পারি না।

হতে পারে আমি প্রকল্পটি অন্য একটি বেসরকারী রেপোতে কাঁটাতে পারলাম, তবে আমি কীভাবে প্রকল্পগুলি স্নিকের মধ্যে রাখতে পারি তা সম্পর্কে নিশ্চিত নই (সমাধান রয়েছে এমন ফাইলটি বাদে)।

এই পরিস্থিতির জন্য কি কোনও কর্মপ্রবাহ রয়েছে?


1
আমি তাই মনে করি না। তবে আপনি যা করছেন তা হ'ল: প্রয়োগের জন্য এলিওর পদ্ধতিগুলির জন্য ডেলচার ইন্টারফেস। আপনার ছাত্র-পাবলিক রেপোতে, খালি পদ্ধতি সংস্থাগুলির সাথে সেই ইন্টারফেসগুলি প্রয়োগ করে শ্রেণি তৈরি করুন। একটি পৃথক বেসরকারী রেপোতে সমাধানগুলি বজায় রাখুন। এটি সম্পূর্ণরূপে আপনার সিঙ্ক্রোনাইজেশন সমস্যার সমাধান করে না তবে এটি এটিকে কার্যের সুযোগগুলিতে কমিয়ে দেয়।
marstato

আপনি শাখাগুলি অ্যাক্সেস নিয়ন্ত্রণ করতে গিথুব এপিআই ব্যবহার করে দেখেছেন?

উত্তর:


8

কি যথেষ্ট করণীয় হতে পারে:

  • 2 টি সংগ্রহশালা তৈরি করুন: ছাত্র এবং শিক্ষক।
  • এগুলি আপনার মেশিনে ক্লোন করুন (গিথুব ক্লায়েন্টের সাথে করা যেতে পারে)
  • আপনি কেবল শিক্ষকেই কাজ করেন , কখনও ছাত্রকে স্পর্শ করেন না।

সুতরাং আপনার ডিরেক্টরি কাঠামো 2 ক্লোন করা গিট রেপো:

  • / ছাত্র (একটি .git ফোল্ডার সহ)
  • / শিক্ষক (একটি .git ফোল্ডার সহ)

আপনি আপনার ভাষার জন্য মন্তব্যগুলিতে "ব্যক্তিগত" কোডের চারপাশে চিহ্নিতকারী রেখেছেন, উদাহরণস্বরূপ নীচে জাভাস্ক্রিপ্ট। চিহ্নিতকারীগুলি নির্দেশ করে যেখানে প্রাইভেট কোড শুরু হয় এবং শেষ হয়।

function sum(a, b) {
  // -----------------------START
  return a + b; // so this is what you expect from the student
  // -----------------------END
}

console.log(sum(1,1)); // I expect 2 as a result of your homework

তারপরে আপনার স্থানীয় মেশিনে একটি সাধারণ স্ক্রিপ্ট তৈরি করুন:

files.forEach((fileContent, fileName) => {
  let newFileContent = '';
  let public = true;
  fileContent.forEach((line) => {
    switch(line) {
      case '// -----------------------START':
        public = false;
        break;
      case '// -----------------------END':
        public = true;
        break;
      default:
        if(public) {
          newFileContent = newFileContent + line + "\n";
        }
    }
  });
  writeFile('../student/' + fileName, newFileContent);
});

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

এটি অনির্ধারিত উদাহরণ কোড, সুতরাং সম্ভবত আপনাকে কিছু ডিবাগিং করতে হবে।

আপনি কেবল আউটপুট সম্পর্কে খুশি হবার পরে আপনাকে কেবল স্টুডেন্ট রিপোজিটরিতে প্রতিশ্রুতিবদ্ধ হওয়া এবং চাপ দিতে হবে। এটি গিটহাব ক্লায়েন্ট ব্যবহার করার সময় এক ক্লিকে করা যেতে পারে (যাতে আপনি দ্রুত চাক্ষুষ পর্যালোচনা করতে পারেন) বা কমান্ড লাইনে নিজে এটি করতে পারেন।

ছাত্র রেপো কেবলমাত্র একটি আউটপুট সংগ্রহশালা তাই এটি সর্বদা আপ টু ডেট থাকে, শিক্ষার্থীদের কাছে কমিটগুলি দেখে কী পরিবর্তন হয়েছে তা স্পষ্ট ((কারণ তারা কেবল পরিবর্তনগুলি দেখায়) এবং এটি পরিচালনা করা সহজ।

আরও একটি পদক্ষেপ হ'ল গিট কমিট-হুক তৈরি করা যা আপনার স্ক্রিপ্টটি স্বয়ংক্রিয়ভাবে চালিত করে।

সম্পাদনা: দেখুন আপনি আপনার পোস্টে একটি সম্পাদনা করেছেন:

স্পষ্টতই আমি চাই না যে শিক্ষার্থীরা সমাধানটিতে অ্যাক্সেস পান (অ্যাসাইনমেন্টটি শেষ না হওয়া পর্যন্ত)।

আমি সন্দেহ করি এটি পরিষ্কার হয়েছে তবে সম্পূর্ণ হওয়া উচিত: সমাপ্ত ব্যায়ামের চারপাশের ট্যাগগুলি সরিয়ে ফেলুন উত্তরগুলি ঠিক একইভাবে প্রকাশ করা হবে যেমনটি আপনি অনুশীলনের স্বাভাবিক আপডেটের জন্য করবেন।


আশা করছিলাম কিছু গিট ভোডো দিয়ে আমি এটি করতে পারি তবে আপনার সমাধানটি খুব ব্যবহারিক।
কেন

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

গিটকে পরিবর্তনের উপর নজর রাখতে আপনি আপনার শিক্ষক রেপোতে একটি ছাত্র শাখা তৈরি করতে পারেন, মার্জ করার সময় স্ক্রিপ্টটি চালান (বা চিহ্নিতকারীদের মধ্যে কিছু মুছে ফেলার মাধ্যমে)। তারপরে স্থানীয়ভাবে শিক্ষার্থীদের শাখা সিঙ্ক করুন এবং এটিকে শিক্ষক উত্সের পরিবর্তে শিক্ষার্থী রেপোতে চাপ দিন। এই পরিবর্তনগুলি ট্র্যাক করার জন্য গিটটি আরও ভাল আকারে থাকবে এবং ইতিহাসটি সঠিকভাবে একটি রেপো থেকে অন্য রেপোতে ফরোয়ার্ড করা থাকবে। দুই ভুবনের সেরা. আমি আপনাকে এই মনে চেষ্টা করে দেখিনি তবে কেন এটি কাজ করবে না তা আমি দেখতে চাই না।
নিউটোপিয়ান

1
প্রারম্ভের শেষের ট্যাগগুলি সরানোর ধারণা বাদে আমি এটিকে পছন্দ করি। "সমাধান" শব্দটি যুক্ত করে তাদের চাঙ্গা করা ভাল।
candied_orange

@ ক্যান্ডিড ওরেঞ্জ এটিও একটি দুর্দান্ত, তাতে সম্মত হন। সমাধানটি কিছু আলাদা ফর্ম্যাটিংকেও অনুমতি দেয় এবং এটি ভুলে যাওয়া ট্যাগ এবং সমাধানটি প্রকাশ করা উচিত এমন বাস্তব সিদ্ধান্তের মধ্যে স্পষ্টভাবে পার্থক্য করে। @ নিউটোপিয়ান: আমি এটি নিয়ে ভাবছিলাম তবে আমি যথেষ্ট সুবিধা দেখিনি। এছাড়াও আমি সিদ্ধান্ত নিয়েছি ছাত্রের আউটপুটটিকে সম্পূর্ণ ভিন্ন ধরণের কোড হিসাবে দেখব। এটি আসল উত্স নয় তাই আমি সিদ্ধান্ত নেওয়ার সিদ্ধান্ত নিই। আমি শিক্ষক রেপোতে শাখাগুলি নিয়ে যা করব উদাহরণস্বরূপ: পরবর্তী সেমিস্টারের জন্য কার্যগুলি নিয়ে কাজ করুন। আপনি প্রস্তুত হয়ে গেলে তাদেরকে মাস্টার হিসাবে মার্জ করুন এবং তারপরে স্ক্রিপ্টটি চালান।
লুক ফ্রাঙ্কেন

6

আপনি পারে

  • আপনি যদি বয়লারপ্লেট কোডটি প্রতিশ্রুতিবদ্ধ হন তবে একটি সার্বজনীন গিটহাবের পুনরায় পোস্টারী তৈরি করুন
  • এই সংগ্রহস্থলটিকে একটি ব্যক্তিগত গিটহাবের সংগ্রহশালা হিসাবে কাঁটাুন
  • কাঁটাযুক্ত ভাণ্ডারগুলিতে অ্যাসাইনমেন্টগুলি সমাধান করুন
  • অ্যাসাইনমেন্টটি সম্পন্ন হওয়ার পরে প্রতিটি সমাধান পাবলিক স্টোরগুলিতে মার্জ করুন

এইভাবে আমি এই কার্যপ্রবাহটি প্রয়োগ করব:

  • assignmentsগিটহাবে হোস্ট করা একটি পাবলিক রিপোস্ট্রি তৈরি করুন । অ্যাসাইনমেন্টের জন্য বয়লারপ্লেট কোড যুক্ত করুন। যেমন প্রতিটি অ্যাসাইনমেন্টের জন্য আপনি অ্যাসাইনমেন্টের বয়লারপ্লেট কোড সহ একটি নতুন উপ-ডিরেক্টরি চালু করেন।
  • গিটহাবের উপর একটি নতুন ব্যক্তিগত সংগ্রহশালা তৈরি করুন assignments-solvedassignmentsআপনার মেশিনে রেপো ক্লোন করুন এবং এটিকে assignments-solved রেপোতে চাপুন (মূলত আপনার নিজস্ব কপি হিসাবে ব্যক্তিগত সংগ্রহস্থলটি কাঁটাচামচ করুন): git clone https://github.com/[user]/assignments assignments-solved cd assignments-solved git remote set-url origin https://github.com/[user]/assignments-solved git push origin master git push --all
  • যোগ assignments-solvedরেপো দূরবর্তী হিসাবে assignmentsরেপো: cd assignments # change to the assignments repo on your machine git remote add solutions https://github.com/[user]/assignments-solved
  • assignments-solvedসংগ্রহস্থল প্রতিটি অ্যাসাইনমেন্ট প্রয়োগ করুন । নিশ্চিত করুন যে প্রতিটি প্রতিশ্রুতিতে কেবল একটি অ্যাসাইনমেন্ট থেকে পরিবর্তন রয়েছে।
  • আপনি রেপোতে একটি solvedশাখা তৈরি করতে চাইতে পারেন assignments, যাতে মূল কাজগুলি পরিবর্তন না হয়: cd assignments # change to the assignments repo on your machine git branch -b solutions git push -u origin
  • আপনি যখন কোনও সমাধান প্রকাশ করতে চান assignments, তখন solvedরিমোটটি cherry-pickআনুন এবং সমাধানগুলি সমেত কমিট করুন। cd assignments # change to the assignments repo on your machine git checkout solved git fetch solutions git cherry-pick [commithash] যেখানে [commithash]আপনার সমাধানের প্রতিশ্রুতিবদ্ধ রয়েছে।

আপনি assignments-solvedরেপোর একটি পৃথক শাখায় প্রতিটি অ্যাসাইনমেন্ট প্রয়োগ করে এবং তারপরে রেপোতে একটি পুল-অনুরোধ তৈরি করে ওয়ার্কফ্লো বাস্তবায়িত করতে সক্ষম হতে পারেন assignments। তবে আমি নিশ্চিত নই যে এটি গিটহাবে কাজ করবে কিনা, কারণ assignments-solvedরেপো আসল কাঁটাচামচ নয়।


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

0

আমি আপনাকে কেবল .gitignoreআপনার ভাণ্ডারে ফাইল-এনিং এবং এনক্রিপ্ট করার উদ্দেশ্যে একটি ইউটিলিটি প্রস্তাব করতে পারি । ওয়ার্কফ্লো ব্যবহার করা কিছুটা শক্ত, তবে এটি আপনার ফাইলের এনক্রিপ্ট হওয়া অংশগুলিকে অন্যান্য অনিচ্ছাকৃত ফাইলগুলির সাথে ওয়ার্কিং কপিতে উপলভ্য করে তোলে, যা তাদের যথারীতি গিট দিয়ে ট্র্যাক করতে দেয়।

#!/bin/bash

set -o errexit
set -o pipefail
set -o nounset

version=1
OPTIND=1
verbose=0
mode="add"
recurse=()
files=()

while getopts ":vaslr:" opt
do
    case "$opt" in
        \?) echo "error: invalid option: -$OPTARG" >&2 ; exit 1
            ;;
        :)  echo "error: option -$OPTARG requires an argument" >&2 ; exit 1
            ;;
        v)  let "verbose++" ; echo "verbosity increased"
            ;;
        a)  mode="add"
            ;;
        s)  mode="save"
            ;;
        l)  mode="load"
            ;;
        r)  recurse+=("$OPTARG")
            ;;
    esac
done
shift $((OPTIND-1))
if [[ "${#recurse[@]}" != 0 ]] 
then
    for pattern in "${recurse[@]}" 
    do
        while IFS= read -d $'\0' -r file
        do
            files+=("$file")
        done < <(find . -name "$pattern" -type f -print0)
    done
else
    files=("$@")
fi

[[ "${#files[@]}" != 0 ]] || { echo "list of files to process is empty" >&2 ; exit 1 ; }

if [[ $mode == "add" ]]
then
    for file in "${files[@]}"
    do
        [[ -e $file ]] && cp "$file" "${file}.bak" || touch "$file"
        sshare_file="${file}.sshare"
        [[ -e $sshare_file ]] || { echo "$version" > "$sshare_file" ; git add --intent-to-add "$sshare_file" ; echo "$file" >> .gitignore ; echo "${file}.bak" >> .gitignore ; git add .gitignore ; }
    done
    exit 0
fi
tmp_dir=`mktemp --tmpdir -d sshare.XXXX`
read -r -s -p "enter password to $mode tracked files:" sshare_password && echo ;
for file in "${files[@]}"
do
    [[ ! -e $file ]] && touch "$file" || cp "$file" "${file}.bak"
    sshare_file="${file}.sshare"
    [[ -r $sshare_file ]] || { echo "warning: can't read file '$sshare_file' (file '$file' skipped)" >&2 ; continue ; }
    file_version=$(head -1 "$sshare_file")
    [[ "$file_version" == $version ]] || { echo "warning: version '$file_version' of '$sshare_file' file differs from version '$version' of script (file '$file' skipped)" >&2 ; continue ; }
    tmp_file="$tmp_dir/$file"
    mkdir -p "$(dirname "$tmp_file")"
    > "$tmp_file"
    line_number=0
    while IFS= read -r line
    do
        let "line_number++" || :
        [[ -n $line ]] || { echo "warning: empty line encountered at #$line_number in file '$sshare_file' (ignored)" >&2 ; continue ; }
        echo "$line" | openssl enc -d -A -base64 -aes256 -k "$sshare_password" | gunzip --to-stdout --force | patch "$tmp_file" --normal --quiet
    done < <(tail --lines=+2 "$sshare_file")
    if [[ $mode == "load" ]]
    then
        cp -f "$tmp_file" . || { echo "warning: can't write to file '$file' (file '$file' skipped)" >&2 ; continue ; }
    elif [[ $mode == "save" ]]
    then
        chunk=$(diff "$tmp_file" "$file" || :)
        [[ -n $chunk ]] || { echo "nothing to comit since last edit for file '$file'" ; continue ; }
        [[ -w $sshare_file ]] || { echo "warning: can't update sshare database '$sshare_file' (file '$file' skipped)" ; continue ; }
        echo "$chunk" | gzip --stdout | openssl enc -e -A -base64 -aes256 -k "$sshare_password" >> "$sshare_file"
        echo >> "$sshare_file"
        echo "changes encrypted for file '$file'"
    fi
done

ফাইলের নাম a.txtটাইপ সহ গোপন ফাইল তৈরি করতে sshare -a a.txt। ইউটিলিটি ফাইল তৈরি a.txtএবং ফাইল যুক্ত .gitignore। তারপরে এটি ফাইলের নামের a.txt.sshareসাথে .sshareএক্সটেনশন যুক্ত করে এনক্রিপ্ট করা "ডাটাবেস" কাউন্টার পার্ট তৈরি করে।

তারপরে আপনি a.txtকিছু পাঠ্য পূরণ করতে পারেন । git commitটাইপের ঠিক আগে এর রাজ্যটি সংরক্ষণ করতে sshare -s a.txt, তারপরে ইউটিলিটি আপনাকে ফাইলের নতুন রাষ্ট্র এনক্রিপ্ট করার জন্য পাসওয়ার্ডের জন্য অনুরোধ করবে a.txt। তারপরে এই পাসওয়ার্ডটি ব্যবহার করে ইউটিলিটি ফাইলের a.txtশেষ এবং বর্তমানের অবস্থার মধ্যে এনক্রিপ্ট করা পার্থক্য যুক্ত করে a.txt.sshare

এনক্রিপ্ট করা ফাইলগুলির সাথে সংগ্রহ / টান সংগ্রহস্থলের পরে আপনার sshareপ্রতিটি ফাইলের -l("লোড") কী ব্যবহার করে ইউটিলিটি চালানো উচিত । *.sshareএক্ষেত্রে ইউটিলিটি ডিক্রিপ্ট ফাইলগুলিকে টেক্সট ফাইলগুলিতে ওয়ার্কিং অনুলিপিতে গিট দ্বারা তালমুক্ত করা যায় ।

আপনি প্রতিটি গোপন ফাইলের জন্য বিভিন্ন পাসওয়ার্ড ব্যবহার করতে পারেন।

উপযোগ ট্র্যাকের Git দক্ষতার পরিবর্তন (অনুমতি দেয় পরিবর্তন এর .sshareফাইল কেবল এক লাইন)।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.