फ़ाइल का एक संस्करण निजी रखने के लिए github रणनीति


11

मैं छात्रों के लिए कोडिंग समस्याएं लिखने वाला एक व्याख्याता हूं। मैं जो करना चाहता हूं वह छात्रों को उन कार्यों के लिए प्लेसहोल्डर्स के साथ बॉयलरप्लेट कोड देना है, जो छात्रों को पूरा करना है। मैं छात्रों को इसे क्लोन करने के लिए एक निजी जीथब रेपो तक पहुंच दूंगा।

हालाँकि, मैं भी नमूना समाधान के साथ पूरा कोडबेस का एक संस्करण चाहते हैं। जाहिर है मैं नहीं चाहता कि छात्रों को समाधान तक पहुंच प्राप्त हो (जब तक कि असाइनमेंट खत्म नहीं हो जाता)।

मैंने शाखाओं के बारे में सोचा है, लेकिन AFAIK, मैं एक शाखा को निजी नहीं रख सकता।

हो सकता है कि मैं इस परियोजना को किसी अन्य निजी रेपो में कांटा कर सकता हूं, लेकिन मैं अनिश्चित हूं कि मैं परियोजनाओं को स्नीक में कैसे रख सकता हूं (फाइल के अलावा जिसमें समाधान शामिल है)।

क्या इस स्थिति के लिए कोई वर्कफ़्लो है?


1
मुझे ऐसा नहीं लगता। लेकिन आप जो करते हैं वह ठंडा हो जाता है: डेलकेयर उन तरीकों के लिए इंटरफेस करता है जिन्हें लागू किया जाना है। अपने छात्र-सार्वजनिक रेपो में, उन तरीकों को लागू करने वाली कक्षाएं बनाएँ, जो खाली पद्धति निकायों के साथ हैं। एक अलग निजी रेपो में समाधान बनाए रखें। यह आपकी सिंक्रनाइज़ेशन समस्या को पूरी तरह से हल नहीं करता है लेकिन यह कार्यों के दायरे को कम कर देता है।
marstato

क्या आपने शाखाओं तक पहुंच को नियंत्रित करने के लिए github API का उपयोग करने के लिए देखा है?

जवाबों:


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);
});

यह होगा: अपनी सभी फाइलें ले लें और कोड के निजी चिह्नित भागों के बिना / छात्र (अधिलेखित) सामग्री को कॉपी करें। अगर आप चाहते हैं कि आप वहां खाली लाइनें डाल सकते हैं, लेकिन यह संकेत दे सकता है कि आपकी उम्मीद किस तरह का समाधान है।

यह अप्रयुक्त उदाहरण कोड है, इसलिए आपको कुछ डिबगिंग करना होगा।

अब केवल एक चीज जो आपको करनी है, वह है और छात्र रिपॉजिटरी में पुश करें जब आप आउटपुट के बारे में खुश हों। GitHub क्लाइंट का उपयोग करते समय एक क्लिक में किया जा सकता है (ताकि आप एक त्वरित दृश्य समीक्षा कर सकें) या बस इसे मैन्युअल रूप से कमांड लाइन पर करें।

छात्र रेपो एक आउटपुट रिपॉजिटरी है केवल इसलिए यह हमेशा अद्यतित रहेगा, यह छात्रों को स्पष्ट है कि कमिट्स को देखकर क्या बदला है (क्योंकि वे केवल परिवर्तन दिखाते हैं) और इसे संभालना आसान है।

एक कदम आगे एक गिट कमिट बनाने के लिए होगा जो आपकी स्क्रिप्ट को स्वतः चलाता है।

संपादित करें: देखें कि आपने अपनी पोस्ट को संपादित किया है:

जाहिर है मैं नहीं चाहता कि छात्रों को समाधान तक पहुंच प्राप्त हो (जब तक कि असाइनमेंट खत्म नहीं हो जाता)।

मुझे लगता है कि यह स्पष्ट है, लेकिन पूरा होने के लिए: बस समाप्त अभ्यास के चारों ओर टैग हटा दें उत्तर को उसी तरह प्रकाशित करेंगे जैसे आप अभ्यास के सामान्य अपडेट के लिए करेंगे।


उम्मीद कर रहा था कि मैं कुछ git voodoo के साथ ऐसा कर सकता हूं, हालांकि आपका समाधान बहुत व्यावहारिक है।
केन

@Ken उस बारे में भी सोच रहा था लेकिन यह गलत काम के लिए थोड़ा गलत उपकरण है। Git विलय, अद्यतन आदि करता है, लेकिन सामान्य तौर पर यह कोड का चयन करने का विचार नहीं है। यह आपके कोडबेस को कई मशीनों पर लगातार बनाए रखने में अच्छा है। इसलिए मैं एक और उपाय है। मुझे इस दृष्टिकोण के बारे में भी पसंद है कि यह जोखिम और श्रम को कम करता है इसलिए इसे साथ रखना आसान है। और, अंत में, आपको अपने छात्रों को एक अच्छा उदाहरण देने के लिए अपने रेपो संदेश को वैसे भी हाथ से लिखना चाहिए।)
ल्यूक फ्रेंकेन

परिवर्तन में मदद करने के लिए आप अपने शिक्षक रेपो में छात्र शाखा बना सकते हैं, मर्ज करते समय स्क्रिप्ट को चलाएं (या मार्करों के बीच कुछ भी हटाकर हाथ से विलय)। फिर छात्र शाखा को स्थानीय रूप से सिंक करें और शिक्षक मूल के बजाय छात्र प्रतिनिधि को धक्का दें। यह तरीका परिवर्तन को ट्रैक करने के लिए बेहतर आकार में होगा और एक रेपो से अगले तक इतिहास को ठीक से आगे बढ़ाया जाएगा। दोनों ओर से लाभदायक। मैंने इस दिमाग की कोशिश नहीं की है, लेकिन मैं नहीं देखता कि यह काम क्यों नहीं करेगा।
१४:१६ पर न्यूटोपियन

1
मुझे यह पसंद है सिवाय स्टार्ट एंड टैग हटाने के विचार के। "समाधान" शब्द जोड़कर उन्हें बेहतर करने के लिए।
कैंडिड_ऑरेंज

@CandiedOrange वह भी एक अच्छा, उस पर सहमत। समाधान कुछ अलग स्वरूपण की भी अनुमति देगा और यह स्पष्ट रूप से भूल गए टैग और समाधान को प्रकाशित करने वाले वास्तविक निर्णय के बीच अंतर करता है। @ newtopian: मैं इस बारे में सोच रहा था लेकिन मुझे इसके पर्याप्त फायदे नहीं दिख रहे थे। इसके अलावा, मैंने छात्र आउटपुट को बिल्कुल अलग तरह के कोड के रूप में देखने का फैसला किया। यह वास्तविक स्रोत नहीं है इसलिए मैंने फैसला किया है कि नहीं। शिक्षक रेपो में शाखाओं के साथ मैं क्या करूँगा उदाहरण के लिए: अगले सेमेस्टर के कार्यों पर काम करें। जब आप तैयार होते हैं तो आप उन्हें मास्टर में विलय कर देते हैं और फिर स्क्रिप्ट चलाते हैं।
ल्यूक फ्रेंकेन

6

आप ऐसा कर सकते हैं

  • एक सार्वजनिक GitHub रिपॉजिटरी बनाएं जो आप बॉयलरप्लेट कोड के लिए प्रतिबद्ध थे
  • एक निजी GitHub भंडार के रूप में इस भंडार को कांटा
  • फोर्क्ड रिपॉजिटरी में असाइनमेंट को हल करें
  • असाइनमेंट किए जाने पर प्रत्येक समाधान को सार्वजनिक रिपॉजिटरी में मर्ज करें

इस प्रकार मैं इस वर्कफ़्लो को लागू करूंगा:

  • assignmentsGitHub पर होस्ट किया गया सार्वजनिक रिपॉजिटरी बनाएँ । असाइनमेंट के लिए बॉयलरप्लेट कोड जोड़ें। प्रत्येक असाइनमेंट के लिए आप असाइनमेंट के बॉयलरप्लेट कोड वाले एक नए उप-निर्देशिका का परिचय देते हैं।
  • GitHub पर एक नया निजी भंडार बनाएँ 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। लेकिन मुझे यकीन नहीं है कि यह GitHub में काम करेगा, क्योंकि assignments-solvedरेपो असली कांटा नहीं है ।


मैंने प्रोग्रामिंग उत्तरों को प्रस्तुत उत्तरों से अलग करने के लिए एक समान विधि का सफलतापूर्वक उपयोग किया है। मेरे मामले में, प्रस्तुत समाधान एक निजी क्लोन की अलग-अलग शाखाओं में जोड़े जाते हैं, और कभी भी सार्वजनिक रेपो में वापस विलय नहीं किया जाता है। मुझे यह देखने का अतिरिक्त लाभ है कि प्रत्येक उम्मीदवार ने परीक्षण का कौन सा संस्करण हल किया है, क्योंकि यह समय के साथ विकसित होता है।
axl

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 कुशलता से बदलता है (अनुमति देता है diff की .sshareफाइलों की एक पंक्ति है)।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.