เป็นไปได้git push
หรือไม่ที่จะปรับใช้เว็บไซต์โดยใช้? ฉันมีเรื่องลางสังหรณ์เกี่ยวกับการใช้git hooksเพื่อทำgit reset --hard
บนฝั่งเซิร์ฟเวอร์ แต่ฉันจะทำอย่างไรให้สำเร็จ
เป็นไปได้git push
หรือไม่ที่จะปรับใช้เว็บไซต์โดยใช้? ฉันมีเรื่องลางสังหรณ์เกี่ยวกับการใช้git hooksเพื่อทำgit reset --hard
บนฝั่งเซิร์ฟเวอร์ แต่ฉันจะทำอย่างไรให้สำเร็จ
คำตอบ:
ผมพบว่าสคริปต์นี้บนเว็บไซต์นี้และดูเหมือนว่าจะทำงานได้ค่อนข้างดี
บนโลคัลสำเนาของคุณให้แก้ไขไฟล์. git / config ของคุณและเพิ่มเว็บเซิร์ฟเวอร์เป็นรีโมต:
[remote "production"]
url = username@webserver:/path/to/htdocs/.git
บนเซิร์ฟเวอร์ให้แทนที่. git / hooks / post-update ด้วยไฟล์นี้ (ในคำตอบด้านล่าง)
เพิ่มการเข้าถึงเพื่อเรียกใช้งานไฟล์ (อีกครั้งบนเซิร์ฟเวอร์):
chmod +x .git/hooks/post-update
ตอนนี้เพียงกดไปที่เว็บเซิร์ฟเวอร์ของคุณและควรอัปเดตสำเนาการทำงานโดยอัตโนมัติ:
git push production
ใช้ไฟล์post-updateด้านล่าง:
บนโลคัลสำเนาของคุณให้แก้ไขไฟล์. git / config ของคุณและเพิ่มเว็บเซิร์ฟเวอร์เป็นรีโมต:
[remote "production"]
url = username@webserver:/path/to/htdocs/.git
บนเซิร์ฟเวอร์ให้แทนที่. git / hooks / post-update ด้วยไฟล์ด้านล่าง
เพิ่มการเข้าถึงเพื่อเรียกใช้งานไฟล์ (อีกครั้งบนเซิร์ฟเวอร์):
chmod +x .git/hooks/post-update
ตอนนี้เพียงกดไปที่เว็บเซิร์ฟเวอร์ของคุณและควรอัปเดตสำเนาการทำงานโดยอัตโนมัติ:
git push production
#!/bin/sh
#
# This hook does two things:
#
# 1. update the "info" files that allow the list of references to be
# queries over dumb transports such as http
#
# 2. if this repository looks like it is a non-bare repository, and
# the checked-out branch is pushed to, then update the working copy.
# This makes "push" function somewhat similarly to darcs and bzr.
#
# To enable this hook, make this file executable by "chmod +x post-update".
git-update-server-info
is_bare=$(git-config --get --bool core.bare)
if [ -z "$is_bare" ]
then
# for compatibility's sake, guess
git_dir_full=$(cd $GIT_DIR; pwd)
case $git_dir_full in */.git) is_bare=false;; *) is_bare=true;; esac
fi
update_wc() {
ref=$1
echo "Push to checked out branch $ref" >&2
if [ ! -f $GIT_DIR/logs/HEAD ]
then
echo "E:push to non-bare repository requires a HEAD reflog" >&2
exit 1
fi
if (cd $GIT_WORK_TREE; git-diff-files -q --exit-code >/dev/null)
then
wc_dirty=0
else
echo "W:unstaged changes found in working copy" >&2
wc_dirty=1
desc="working copy"
fi
if git diff-index --cached HEAD@{1} >/dev/null
then
index_dirty=0
else
echo "W:uncommitted, staged changes found" >&2
index_dirty=1
if [ -n "$desc" ]
then
desc="$desc and index"
else
desc="index"
fi
fi
if [ "$wc_dirty" -ne 0 -o "$index_dirty" -ne 0 ]
then
new=$(git rev-parse HEAD)
echo "W:stashing dirty $desc - see git-stash(1)" >&2
( trap 'echo trapped $$; git symbolic-ref HEAD "'"$ref"'"' 2 3 13 15 ERR EXIT
git-update-ref --no-deref HEAD HEAD@{1}
cd $GIT_WORK_TREE
git stash save "dirty $desc before update to $new";
git-symbolic-ref HEAD "$ref"
)
fi
# eye candy - show the WC updates :)
echo "Updating working copy" >&2
(cd $GIT_WORK_TREE
git-diff-index -R --name-status HEAD >&2
git-reset --hard HEAD)
}
if [ "$is_bare" = "false" ]
then
active_branch=`git-symbolic-ref HEAD`
export GIT_DIR=$(cd $GIT_DIR; pwd)
GIT_WORK_TREE=${GIT_WORK_TREE-..}
for ref
do
if [ "$ref" = "$active_branch" ]
then
update_wc $ref
fi
done
fi
หลังจากลองผิดลองถูกหลายคนและปลายตายฉันในที่สุดก็สามารถที่จะปรับใช้โค้ดของเว็บไซต์ที่มีเพียง "ดันคอมไพล์ระยะไกล " ต้องขอบคุณบทความนี้
สคริปต์หลังการอัปเดตของผู้เขียนมีความยาวเพียงหนึ่งบรรทัดและโซลูชันของเขาไม่ต้องการการกำหนดค่า. htaccess เพื่อซ่อน repo Git เหมือนกับที่คนอื่นทำ
คู่ของบล็อกที่สะดุดถ้าคุณกำลังปรับใช้นี้ในอินสแตนซ์ของ Amazon EC2
1) ถ้าคุณใช้ sudo เพื่อสร้างพื้นที่เก็บข้อมูลปลายทางเปล่าคุณต้องเปลี่ยนเจ้าของ repo เป็นผู้ใช้ ec2 มิเช่นนั้นการกดจะล้มเหลว (ลอง "chown ec2-user: repoผู้ใช้ ec2 ")
2) การพุชจะล้มเหลวหากคุณไม่ได้กำหนดค่าตำแหน่งล่วงหน้าของamazon-private-key .pem ของคุณใน / etc / ssh / ssh_config เป็นพารามิเตอร์ IdentityFile หรือใน ~ / .ssh / config โดยใช้ "[ โฮสต์] - ชื่อโฮสต์ - IdentityFile - โครงร่างผู้ใช้ "อธิบายไว้ที่นี่ ...
... อย่างไรก็ตามหากมีการกำหนดค่าโฮสต์ใน ~ / .ssh / config และแตกต่างจากชื่อโฮสต์การกด Git จะล้มเหลว (นั่นอาจเป็นข้อผิดพลาด Git)
อย่าติดตั้งคอมไพล์บนเซิร์ฟเวอร์หรือคัดลอกโฟลเดอร์. git ที่นั่น เพื่ออัปเดตเซิร์ฟเวอร์จาก git clone คุณสามารถใช้คำสั่งต่อไปนี้:
git ls-files -z | rsync --files-from - --copy-links -av0 . user@server.com:/var/www/project
คุณอาจต้องลบไฟล์ที่ถูกลบออกจากโครงการ
นี่เป็นการคัดลอกไฟล์ที่เช็คอินทั้งหมด rsync ใช้ ssh ซึ่งติดตั้งบนเซิร์ฟเวอร์อย่างไรก็ตาม
ยิ่งคุณติดตั้งซอฟต์แวร์บนเซิร์ฟเวอร์น้อยลงเท่าไหร่ก็ยิ่งมีความปลอดภัยมากขึ้นและจัดการการกำหนดค่าและจัดการเอกสารได้ง่ายขึ้น นอกจากนี้ยังไม่จำเป็นต้องเก็บโคลนคอมไพล์อย่างสมบูรณ์บนเซิร์ฟเวอร์ มันทำให้ซับซ้อนมากขึ้นเพื่อรักษาความปลอดภัยทุกอย่างอย่างถูกต้อง
สิ่งสำคัญที่คุณต้องทำมีดังต่อไปนี้:
server = $1
branch = $2
git push $server $branch
ssh <username>@$server "cd /path/to/www; git pull"
ฉันมีบรรทัดเหล่านั้นในแอปพลิเคชันของฉันซึ่งเรียกใช้งานdeploy
ได้
./deploy myserver mybranch
ดังนั้นเมื่อผมต้องการจะปรับประเภท
ssh -A ...
git pull
ควรหลีกเลี่ยงสำหรับการใช้งานโดยอัตโนมัติเพราะเป็นส่วนหนึ่งของการผสานก็อาจจำเป็นต้องมีการทำความสะอาดด้วยตนเองหากมีความขัดแย้งใด ๆ
วิธีที่ฉันทำคือฉันมีที่เก็บ Git เปลือยบนเซิร์ฟเวอร์การปรับใช้ของฉันที่ฉันผลักดันการเปลี่ยนแปลง จากนั้นฉันล็อกอินเข้าสู่เซิร์ฟเวอร์การปรับใช้เปลี่ยนเป็นไดเรกทอรีเอกสารเว็บเซิร์ฟเวอร์จริงและทำ git pull ฉันไม่ใช้ hooks ใด ๆ เพื่อพยายามทำสิ่งนี้โดยอัตโนมัติดูเหมือนว่าจะมีปัญหามากกว่าที่ควรค่า
git reset
เพื่อย้ายกลับไปมาระหว่างการเปลี่ยนแปลงล่าสุด (ทุกการกระทำไม่ใช่แค่การดึงทั้งหมด) หากคุณต้องการย้อนกลับสิ่งที่เฉพาะเจาะจงที่ไม่ใช่การคอมมิทล่าสุดคุณสามารถใช้git revert
แต่ควรใช้ในกรณีฉุกเฉินเท่านั้น ( git revert
สร้างคอมมิชชันใหม่ที่ยกเลิกผลกระทบของการคอมมิชชันก่อนหน้านี้)
git config --local receive.denyCurrentBranch updateInstead
เพิ่มใน Git 2.3 นี่อาจเป็นโอกาสดี: https://github.com/git/git/blob/v2.3.0/Documentation/config.txt#L2155
คุณตั้งค่าบนพื้นที่เก็บข้อมูลเซิร์ฟเวอร์และยังปรับปรุงต้นไม้การทำงานถ้ามันสะอาด
ได้มีการปรับปรุงต่อไปใน 2.4 กับเบ็ดและการจัดการของสาขาในครรภ์push-to-checkout
ตัวอย่างการใช้งาน:
git init server
cd server
touch a
git add .
git commit -m 0
git config --local receive.denyCurrentBranch updateInstead
cd ..
git clone server local
cd local
touch b
git add .
git commit -m 1
git push origin master:master
cd ../server
ls
เอาท์พุท:
a
b
สิ่งนี้มีข้อบกพร่องดังต่อไปนี้ที่กล่าวถึงในประกาศ GitHub :
แต่คะแนนทั้งหมดเหล่านี้อยู่นอกขอบเขตของ Git และต้องได้รับการดูแลจากโค้ดภายนอก ดังนั้นในแง่นี้สิ่งนี้ร่วมกับ Git hooks จึงเป็นทางออกที่ดีที่สุด
ปรับปรุง: ตอนนี้ผมใช้ลอยด์มัวssh -A ...
แก้ปัญหากับตัวแทนที่สำคัญ ผลักไปที่ repo หลักแล้วดึงมันขนานกับเครื่องทั้งหมดของคุณเร็วขึ้นเล็กน้อยและต้องใช้การตั้งค่าน้อยลงในเครื่องเหล่านั้น
ไม่เห็นโซลูชันนี้ที่นี่ เพียงแค่กดผ่าน ssh หากมีการติดตั้ง git บนเซิร์ฟเวอร์
คุณจะต้องมีรายการต่อไปนี้ใน. git / config ในพื้นที่ของคุณ
[remote "amazon"]
url = amazon:/path/to/project.git
fetch = +refs/heads/*:refs/remotes/amazon/*
แต่เฮ้นั่นมันอะไรกันamazon:
? ในโลคัล ~ / .ssh / config ของคุณคุณจะต้องเพิ่มรายการต่อไปนี้:
Host amazon
Hostname <YOUR_IP>
User <USER>
IdentityFile ~/.ssh/amazon-private-key
ตอนนี้คุณสามารถโทร
git push amazon master
ssh <USER>@<YOUR_IP> 'cd /path/to/project && git pull'
(BTW: /path/to/project.git แตกต่างจากไดเรกทอรีการทำงาน / เส้นทาง / ไปยัง / โครงการจริง)
ในสถานการณ์ของเราเรากำลังจัดเก็บรหัสไว้บน github / bitbucket และต้องการปรับใช้กับเซิร์ฟเวอร์ที่ใช้งานจริง ในกรณีนี้ชุดค่าผสมต่อไปนี้ใช้ได้กับเรา(นั่นคือรีมิกซ์ของคำตอบที่ได้รับการโหวตอย่างสูงที่นี่) :
.git
ไดเรกทอรีของคุณไปยังเว็บเซิร์ฟเวอร์ของคุณgit remote add live ssh://user@host:port/folder
git config receive.denyCurrentBranch ignore
บนรีโมต: nano .git/hooks/post-receive
และเพิ่มเนื้อหานี้:
#!/bin/sh
GIT_WORK_TREE=/var/www/vhosts/example.org git checkout -f
บนรีโมท: chmod +x .git/hooks/post-receive
git push live
หาก.git
โฟลเดอร์ของคุณอยู่ในรูทเอกสารตรวจสอบให้แน่ใจว่าคุณซ่อนมันจากด้านนอกด้วยการเพิ่ม.htaccess
(ที่มา ):
RedirectMatch 404 /\..*$
เราใช้capistranoสำหรับการจัดการการปรับใช้ เราสร้าง capistrano เพื่อปรับใช้บนเซิร์ฟเวอร์ staging แล้วเรียกใช้ rsync กับเซิร์ฟเวอร์ทั้งหมดของเรา
cap deploy
cap deploy:start_rsync (when the staging is ok)
ด้วย capistrano เราสามารถย้อนกลับได้ง่ายในกรณีที่เกิดข้อผิดพลาด
cap deploy:rollback
cap deploy:start_rsync
Giddyupเป็นตะขอคอมไพล์เพียงเพิ่มภาษาน้ำไม่เชื่อเรื่องพระเจ้าเพื่อทำการติดตั้งโดยอัตโนมัติผ่านการกด git นอกจากนี้ยังช่วยให้คุณมีตะขอเริ่ม / หยุดที่กำหนดเองสำหรับการรีสตาร์ทเว็บเซิร์ฟเวอร์อุ่นเครื่องแคช ฯลฯ
ดูเหมือนว่าคุณควรมีสำเนาสองชุดบนเซิร์ฟเวอร์ของคุณ สำเนาเปลือยที่คุณสามารถผลักดัน / ดึงซึ่งคุณจะผลักดันการเปลี่ยนแปลงของคุณเมื่อเสร็จแล้วคุณจะคัดลอกสิ่งนี้ลงในสารบบเว็บของคุณและตั้ง cronjob เพื่ออัปเดต git pull จากสารบบเว็บของคุณทุกวันหรือ ดังนั้น.
คุณสามารถตั้งค่า git hook ได้ซึ่งเมื่อพูดว่าคอมมิชชันทำเพื่อพูดว่า "เสถียร" สาขามันจะดึงการเปลี่ยนแปลงและนำไปใช้กับไซต์ PHP ข้อเสียใหญ่คือคุณจะไม่สามารถควบคุมได้มากนักหากมีสิ่งผิดปกติและจะเพิ่มเวลาในการทดสอบของคุณ - แต่คุณสามารถทราบได้ว่าจะต้องมีการทำงานมากแค่ไหนเมื่อคุณรวมสาขาของคุณไว้ในสาขามั่นคง วิธีการหลายความขัดแย้งที่คุณอาจทำงานเป็น มันเป็นสิ่งสำคัญที่จะต้องคอยจับตาดูไฟล์ใด ๆ ที่มีเฉพาะไซต์ (เช่นไฟล์กำหนดค่า) เว้นแต่คุณจะตั้งใจที่จะเรียกใช้เพียงไซต์เดียวเท่านั้น
คุณได้มองเข้าไปในการผลักดันการเปลี่ยนแปลงไปยังเว็บไซต์แทน?
สำหรับข้อมูลเกี่ยวกับ git hooks ดูที่เอกสารประกอบของgithooks
การใช้วิธีการแก้ปัญหาของคริสเตียน
git archive --prefix=deploy/ master | tar -x -C $TMPDIR | rsync $TMPDIR/deploy/ --copy-links -av username@server.com:/home/user/my_app && rm -rf $TMPDIR/deploy
ฉันใช้โซลูชันต่อไปนี้โดยtoroid.orgซึ่งมีสคริปต์เบ็ดที่เรียบง่ายกว่า
บนเซิร์ฟเวอร์:
$ mkdir website.git && cd website.git
$ git init --bare
Initialized empty Git repository in /home/ams/website.git/
และติดตั้ง hook บนเซิร์ฟเวอร์:
$ mkdir /var/www/www.example.org
$ cat > hooks/post-receive
#!/bin/sh
GIT_WORK_TREE=/var/www/www.example.org git checkout -f
GIT_WORK_TREE=/var/www/www git clean -f -d # clean directory from removed files
$ chmod +x hooks/post-receive
ลูกค้าของคุณ:
$ mkdir website && cd website
$ git init
Initialized empty Git repository in /home/ams/website/.git/
$ echo 'Hello, world!' > index.html
$ git add index.html
$ git commit -q -m "The humble beginnings of my web site."
$ git remote add web ssh://server.example.org/home/ams/website.git
$ git push web +master:refs/heads/master
จากนั้นเพื่อเผยแพร่เพียงพิมพ์
$ git push web
มีคำอธิบายแบบเต็มบนเว็บไซต์: http://toroid.org/ams/git-website-howto
git push web +master:refs/heads/master
แทนที่จะเป็นแค่git push web master
?
ในฐานะที่เป็นคำตอบที่สมบูรณ์ฉันต้องการที่จะเสนอทางเลือกอื่น ฉันใช้ git-ftp และใช้งานได้ดี
https://github.com/git-ftp/git-ftp
ใช้งานง่ายเพียงพิมพ์:
git ftp push
และคอมไพล์จะอัปโหลดไฟล์โครงการโดยอัตโนมัติ
ความนับถือ
กำหนดสภาพแวดล้อมที่คุณมีนักพัฒนาหลายคนเข้าถึงที่เก็บเดียวกันแนวทางต่อไปนี้อาจช่วยได้
ตรวจสอบให้แน่ใจว่าคุณมีกลุ่ม unix ที่ devs ทั้งหมดเป็นเจ้าของและมอบสิทธิ์การเป็นเจ้าของพื้นที่เก็บข้อมูล. git ให้กับกลุ่มนั้น
ใน. git / config ของที่เก็บเซิร์ฟเวอร์ชุด sharedrepository = true (สิ่งนี้บอกให้คอมไพล์อนุญาตผู้ใช้หลายคนซึ่งจำเป็นสำหรับการคอมมิทและการปรับใช้
ตั้ง umask ของผู้ใช้แต่ละคนในไฟล์ bashrc ของพวกเขาให้เหมือนกัน - 002 เป็นการเริ่มต้นที่ดี
ฉันลงเอยด้วยการสร้างเครื่องมือการปรับใช้พื้นฐานของฉันเองซึ่งจะดึงการอัปเดตใหม่จาก repo โดยอัตโนมัติ - https://github.com/jesalg/SlimJim - โดยทั่วไปจะฟัง github post-receive-hook และใช้พร็อกซีเพื่อเรียก อัปเดตสคริปต์
ฉันใช้สองวิธีแก้ไขสำหรับการขอ post:
โซลูชั่น DEPLOY 1
#!/bin/bash
# /git-repo/hooks/post-receive - file content on server (chmod as 755 to be executed)
# DEPLOY SOLUTION 1
export GIT_DIR=/git/repo-bare.git
export GIT_BRANCH1=master
export GIT_TARGET1=/var/www/html
export GIT_BRANCH2=dev
export GIT_TARGET2=/var/www/dev
echo "GIT DIR: $GIT_DIR/"
echo "GIT TARGET1: $GIT_TARGET1/"
echo "GIT BRANCH1: $GIT_BRANCH1/"
echo "GIT TARGET2: $GIT_TARGET2/"
echo "GIT BRANCH2: $GIT_BRANCH2/"
echo ""
cd $GIT_DIR/
while read oldrev newrev refname
do
branch=$(git rev-parse --abbrev-ref $refname)
BRANCH_REGEX='^${GIT_BRANCH1}.*$'
if [[ $branch =~ $BRANCH_REGEX ]] ; then
export GIT_WORK_TREE=$GIT_TARGET1/.
echo "Checking out branch: $branch";
echo "Checking out to workdir: $GIT_WORK_TREE";
git checkout -f $branch
fi
BRANCH_REGEX='^${GIT_BRANCH2}.*$'
if [[ $branch =~ $BRANCH_REGEX ]] ; then
export GIT_WORK_TREE=$GIT_TARGET2/.
echo "Checking out branch: $branch";
echo "Checking out to workdir: $GIT_WORK_TREE";
git checkout -f $branch
fi
done
โซลูชัน DEPLOY 2
#!/bin/bash
# /git-repo/hooks/post-receive - file content on server (chmod as 755 to be executed)
# DEPLOY SOLUTION 2
export GIT_DIR=/git/repo-bare.git
export GIT_BRANCH1=master
export GIT_TARGET1=/var/www/html
export GIT_BRANCH2=dev
export GIT_TARGET2=/var/www/dev
export GIT_TEMP_DIR1=/tmp/deploy1
export GIT_TEMP_DIR2=/tmp/deploy2
echo "GIT DIR: $GIT_DIR/"
echo "GIT TARGET1: $GIT_TARGET1/"
echo "GIT BRANCH1: $GIT_BRANCH1/"
echo "GIT TARGET2: $GIT_TARGET2/"
echo "GIT BRANCH2: $GIT_BRANCH2/"
echo "GIT TEMP DIR1: $GIT_TEMP_DIR1/"
echo "GIT TEMP DIR2: $GIT_TEMP_DIR2/"
echo ""
cd $GIT_DIR/
while read oldrev newrev refname
do
branch=$(git rev-parse --abbrev-ref $refname)
BRANCH_REGEX='^${GIT_BRANCH1}.*$'
if [[ $branch =~ $BRANCH_REGEX ]] ; then
export GIT_WORK_TREE=$GIT_TARGET1/.
echo "Checking out branch: $branch";
echo "Checking out to workdir: $GIT_WORK_TREE";
# DEPLOY SOLUTION 2:
cd $GIT_DIR/; mkdir -p $GIT_TEMP_DIR1;
export GIT_WORK_TREE=$GIT_TEMP_DIR1/.
git checkout -f $branch
export GIT_WORK_TREE=$GIT_TARGET1/.
rsync $GIT_TEMP_DIR1/. -v -q --delete --delete-after -av $GIT_TARGET1/.
rm -rf $GIT_TEMP_DIR1
fi
BRANCH_REGEX='^${GIT_BRANCH2}.*$'
if [[ $branch =~ $BRANCH_REGEX ]] ; then
export GIT_WORK_TREE=$GIT_TARGET2/.
echo "Checking out branch: $branch";
echo "Checking out to workdir: $GIT_WORK_TREE";
# DEPLOY SOLUTION 2:
cd $GIT_DIR/; mkdir -p $GIT_TEMP_DIR2;
export GIT_WORK_TREE=$GIT_TEMP_DIR2/.
git checkout -f $branch
export GIT_WORK_TREE=$GIT_TARGET2/.
rsync $GIT_TEMP_DIR2/. -v -q --delete --delete-after -av $GIT_TARGET2/.
rm -rf $GIT_TEMP_DIR2
fi
done
โซลูชันทั้งสองนั้นใช้วิธีแก้ไขปัญหาก่อนหน้านี้ในหัวข้อนี้
หมายเหตุ BRANCH_REGEX = '^ $ {GIT_BRANCH1} $ 'ตัวกรองสำหรับชื่อสาขาที่ตรงกับสตริง"master " หรือ "dev *" และปรับใช้แผนผังการทำงานหากสาขาที่ถูกพุชตรงกัน สิ่งนี้ทำให้เป็นไปได้ในการปรับใช้รุ่น dev และเวอร์ชันหลักไปยังสถานที่ที่แตกต่างกัน
DEPLOY SOLUTION 1 จะลบเฉพาะไฟล์ซึ่งเป็นส่วนหนึ่งของ repo และถูกลบโดยคอมมิชชัน มันเร็วกว่า Deployment Solution 2
DEPLOY SOLUTION 2 มีข้อดีคือมันจะลบไฟล์ใหม่ใด ๆ ออกจากไดเรกทอรีการผลิตซึ่งถูกเพิ่มเข้าไปในฝั่งเซิร์ฟเวอร์ไม่ว่าจะถูกเพิ่มลงใน repo หรือไม่ มันจะทำความสะอาด repe ของ repo เสมอ ช้ากว่า Deployment Solution 1