TLDR;目标是通过尽可能避免重复代码来维护两个代码(如果可能的话,在一个回购上,如果不是在两个回购上),一个包含练习,另一个包含更正。普通用户不应该能够读取更正的代码。任何把戏都是受欢迎的。
长版本:
我试着做以下的事情:我们的想法是,我们是一些“老师”,我们正在为我们的学生做一些编程练习。通常我们有三种“资源”:
学生可以访问但理论上不应该修改的CI...)
的修正)。
我们到目前为止所做的是,我们有两个回收站,一个是私人的,一个是教师的,一个是公共的,一个是学生的,然后学生们把公共渠道分叉成一个私人的渠道,增加教师作为维护人员,然后从这里开始工作。
但是,在两个存储库之间重复代码有点烦人。git (或者更确切地说,gitlab是我们使用的工具,我们正在使用CI来自动测试学生的代码)是否可以提供更明智的选项来保护一些文件不被读取/克隆?或者,还有其他方法可以轻松地维护两个仅由一个文件不同的存储库吗?
发布于 2020-01-23 17:03:49
您可以有两个远程存储库,比如solution (包含私有代码)和student (包含学生需要处理的公共代码)。
将除解决方案以外的所有代码放在solution中的分支solution中。在b2上创建一个新的分支b1,并将私有代码推到那里。然后,只将分支b1与另一个远程student同步。
然后,学生们可以从那里分叉student并开始工作。如果您需要比较代码,可以将git diff与您的私有分支一起使用,以查看所有已更改的内容。还可以将对学生代码中特定文件的更改合并到新的b1分支,以便快速丢弃任何其他更改。
发布于 2020-01-23 19:37:52
我使用了GoodDeeds提出的方法(谢谢!),但为了合并这两个分支,我编写了一些脚本(易于与其他教师共享),这些脚本可能对其他人有用:
通过确保FILES_TO_REMOVE中的文件不出现在学生版本中,并且FILES_NOT_MERGED不再同步,从而合并分支的脚本。
#!/usr/bin/env bash
# This script will move the teacher changes on the student branch... except
# for the solutions and the scripts files.
set -e
# https://stackoverflow.com/questions/4691956/how-to-make-bash-expand-wildcards-in-variables
function expand { for arg in "$@"; do [[ -f $arg ]] && echo $arg; done }
#### /!\ Lines to edit if you add some more files to correct! ####
FILES_TO_REMOVE=$(expand gestion/*)
FILES_NOT_MERGED=$(expand mono.py cesar.py)
BRANCH=$(git rev-parse --abbrev-ref HEAD)
if [[ "$BRANCH" != "master" ]]; then
echo '/!\ Please go first on master branch.';
exit 1;
fi
# Go to the root folder
cd $(git rev-parse --show-toplevel)
# Go on the student branch
git checkout students
# merge but don't commit yet
echo "### If you see some errors on the next line about"
echo "### conflicts with a file that should be removed,"
echo "### it's not important."
git merge --no-ff --no-commit master || true
# Remove files if needed
for FILE in $FILES_TO_REMOVE
do
echo "- Removing file $FILE..."
git rm "$FILE" || true
done
# reset the files we don't want to commit
for FILE in $FILES_NOT_MERGED
do
echo "- Reseting $FILE..."
# Undo changes made on the files
git reset HEAD "$FILE" || true
echo " Checkout..."
git checkout -- "$FILE" || true
done
echo "### Git status:"
git status
read -p "### Is the last git status fine for you? [Y/n] " -n 1 -r
echo # (optional) move to a new line
echo "The reply is '$REPLY'"
if [[ $REPLY =~ ^[^Yy]+$ ]]
then
echo "You are not happy with the last status?"
echo "Then manually fix the conflits/issues,"
echo "eventually commit with:"
echo " $ git commit -m \"Merged master\""
echo "and when you are done come back on"
echo "the master branch with:"
echo "$ git checkout master"
exit 1
fi
git commit -m "Merged master"
echo "### Status of student branch:"
git status
echo "### Checkout back on master:"
git checkout master
echo "########################################"
echo "### Congrats, the branch is synced ! ###"
echo "########################################"我还编写了一个脚本来自动将students分支推到第二个远程的master分支上:
#!/usr/bin/env bash
# This script will push the students branch on the student online repo.
set -e
NAME_REMOVE="students_repo"
DEFAULT_REMOTE="https://gitlab.com/3i024_2020/tme_01_mono_students"
if ! git config "remote.${NAME_REMOTE}.url" > /dev/null; then
echo "### I will add a new remote named 'students_repo'."
echo "What is the adress of this remote? (default is '${DEFAULT_REMOTE}'):"
read -p "" remote
remote=${remote:-$DEFAULT_REMOTE}
git remote add students_repo "$remote"
echo "New remote created!"
fi
echo "### Please, make sure you merged your branch with the student branch with:"
echo "$ gestion/merge_student.sh "
echo ""
echo "### I will now push the students branch on the master branch"
echo "### of the 'students_repo' remote."
git push students_repo students:master
echo "### Done!"https://stackoverflow.com/questions/59882625
复制相似问题