Try   HackMD

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

Introduction to git


Χρήση version control

  • Προτερήματα:
    • Εύκολη αρχικοποίηση
    • Πλήρες και αναζητήσιμο ιστορικό αλλαγών
    • Ευκολότερη συνεργασία στην ανάπτυξη του κώδικα
  • Αρνητικά:
    • Προσθήκη επιπλέων διαδικασιών
    • Ακατάλληλο για αρχεία που δεν είναι text based
  • Δημοφιλή συνεργατικά εργαλεία:
    • GitHub (μεγάλη κοινότητα χρηστών)
    • GitLab (εύκολη υλοποίηση "on-prem")

Δημοφιλή εργαλεία version control

Κεντρικοποιημένα

  • cvs
  • subversion

Κατανεμημένα

  • git
  • mercurial

Μερικές βασικές έννοιες

  • commit: ένα καταγεγραμμένο σύνολο αλλαγών. Τα commits αποτελούν εικόνες ("snapshots") του κώδικά μας οπότε και μπορούμε να επανέλθουμε σε αυτά αν το θελήσουμε
  • repository (αποθετήριο): όλο το ιστορικό ενός κώδικα/project
  • branches: κλαδιά ανάπτυξης (το default branch στο git ονομάζεται master ή main)

Αρχικοποίηση περιβάλλοντος

$ git config --global user.name "John Doe"
$ git config --global user.email "john@example.com"

ή εναλλακτικά:

$ git config --global --edit

Βοήθεια!

Όλες οι εντολές του git συντάσσονται ως δύο λέξεις, π.χ.:

$ git branch ...
$ git remote ...
$ git clone ...
$ git commit ...

Για να δούμε το εκάστοτε help page απλά δίνουμε στην εντολή που μας ενδιαφέρει την παράμετρο --help, δηλαδή:

$ git branch --help
$ git remote --help
$ git clone --help
$ git commit --help

Αρχικοποίηση repository

$ cd Desktop/shell-lesson-data
$ ls -lR
$ ls -la
$ git init
$ ls -la
$ git status
On branch main

No commits yet

...

Stage and commit

Στο git υπάρχει η έννοια της προετοιμασίας (staging) ενός commit. Όσα αρχεία (ή αλλαγές) κρίνεται ότι είναι έτοιμα γίνονται stage για commit με την git add, π.χ:

$ git add semester_a
$ git status
On branch main

No commits yet

Changes to be committed:
  (use "git rm --cached <file>..." to unstage)
	new file:   semester_a/parser.sh
	new file:   semester_a/schedule.txt
	new file:   semester_a/students.txt
...

Για να γίνουν commit οι αλλαγές χρησιμοποιούμε την git commit.

$ git commit -m "Committed exercise A"
[main (root-commit) d37b3ae] Committed exercise A
 3 files changed, 25 insertions(+)
 create mode 100755 semester_a/parser.sh
 create mode 100644 semester_a/schedule.txt
 create mode 100644 semester_a/students.txt

Όταν εκτελείται η git commit το Git μαζεύει τα αρχεία που κάναμε stage με την git add και αποθηκεύει ένα αντίγραφο μέσα στον φάκελο .git. Αυτό το αντίγραφο αποτελεί το commit και το d37b3ae είναι το αναγνωριστικό του.

maind37b3ae

Με την παράμετρο -m δώσαμε το commit message (την περιγραφή των αλλαγών). Καλό είναι το μήνυμα αυτό να είναι περιεκτικό και να συμπληρώνει την πρόταση "this commit will/does/is". Για περαιτέρω διάβασμα:


Ας προχωρήσουμε να προσθέσουμε και το 2ο φάκελο σε νέο commit:

$ git add duckduckgo/
$ git commit -m "Committed exercise B"
[main a756907] Committed exercise B
 1 file changed, 5 insertions(+)
 create mode 100755 duckduckgo/ddg.sh

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →
θα μπορουσαμε να είχαμε προσθέσει και τους δύο φακέλους με ένα commit, αλλά κάναμε δύο commit περισσότερο ως άσκηση.)


Aν εκτελέσουμε τώρα πλέον git status βλέπουμε τα εξής:

$ git status
On branch main
nothing to commit, working tree clean

Επιπλέον με την git log μπορούμε να δούμε το ιστορικό των αλλαγώ:

$ git log --oneline
a756907 (HEAD -> main) Committed exercise B
d37b3ae Committed exercise A
maind37b3aea756907

Ας κάνουμε λίγες αλλαγές

Π.χ. ας αλλάξουμε το username zzz σε beta χρησιμοποιώντας έναν editor, π.χ.:

$ vim semester_a/schedule.txt
$ vim semester_a/students.txt

Πριν κάνουμε οτιδήποτε μπορούμε να δούμε τι αλλαγές κάναμε ως diff με την εντολή git diff:

$ git diff
...

Αν οι αλλαγές είναι ΟΚ μπορούμε να προχωρήσουμε σε stage (git add) και commit (git commit):

$ git add semester_a
$ git commit -m "Change username zzz to beta"
[main 0a828a1] Change username zzz to beta
 2 files changed, 9 insertions(+), 9 deletions(-)
maind37b3aea7569070a828a1

Αναζήτηση αλλαγών

$ git diff HEAD~1 semester_a/students.txt

ή

$ git diff a756907 semester_a/students.txt

Αναίρεση αλλαγών που δεν έχουν γίνει commit

$ echo -n > semester_a/students.txt
$ cat semester_a/students.txt
$ git checkout semester_a/students.txt
Updated 1 path from the index
$ cat semester_a/students.txt
...

Αναίρεση αλλαγών που έχουν γίνει commit

$ echo -n > semester_a/students.txt
$ git add semester_a/students.txt
$ git commit -m "The wrong commit"
[main a273d51] The wrong commit
 1 file changed, 6 deletions(-)
maind37b3aea7569070a828a1a273d51

Ο τρόπος να αναιρέσουμε ένα commit είναι με την git revert η οποία δέχεται ως όρισμα ένα commit id και επί της ουσίας εφαρμόζει ένα νέο commit με το "αρνητικό" του commit id.

$ git revert a273d51
[main 53f1c5e] Revert "The wrong commit"
 1 file changed, 6 insertions(+)
maind37b3aea7569070a828a1a273d5153f1c5e

.gitignore

Αν έχουμε αρχεία που δεν θέλουμε να αποτελέσουν μέρος του repository (π.χ. αρχεία με κωδικούς ή binary αρχεία) τότε χρησιμοποιούμε το αρχείο .gitignore ώστε να υποδείξουμε στο git ποιά είναι τα αρχεία αυτά που δεν θέλουμε να γίνονται track. Ας φτιάξουμε μερικά αρχεία για να δούμε πώς δουλεύει:

$ touch {a,b}.bin
$ mkdir results
$ touch results/c.out
$ git status
On branch main
Untracked files:
  (use "git add <file>..." to include in what will be committed)
	a.bin
	b.bin
	results/

nothing added to commit but untracked files present (use "git add" to track)

Ας χρησιμοποιήσουμε το .gitignore

$ vim .gitignore
$ cat .gitignore
*.bin
results/
$ git status    
On branch main
Untracked files:
  (use "git add <file>..." to include in what will be committed)
	.gitignore

nothing added to commit but untracked files present (use "git add" to track)
$ git add .gitignore
$ git commit -m "Ignore binary files and the results folder"
[main ebc0636] Ignore binary files and the results folder
 1 file changed, 2 insertions(+)
 create mode 100644 .gitignore
$ git status
On branch main
nothing to commit, working tree clean
maind37b3aea7569070a828a1a273d5153f1c5eebc0636

Git remotes

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →
Θα χρησιμοποιήσουμε το GitLab instance του ΚΗΔ για το demo μας. Στην περίπτωση του GitHub οι ενέργειες που θα πρέπει να ακολουθήσουμε είναι παρόμοιες.

Αν είναι η πρώτη φορά που χρησιμοποιείτε το GitLab προκειμένου να χρησιμοποιήσετε ssh για την μεταφορά των περιεχομένων του τοπικού Git repository θα χρειαστεί να ανεβάσετε το public ssh κλειδί σας στο GitLab. Αυτό το κάνετε επιλέγοντας από το avatar σας Edit Profile -> SSH Keys -> Add new key. Αν δεν έχετε φτιάξει ssh κλειδί μπορείτε να φτιάξετε ένα με την εντολή ssh-keygen.

Για να φτιάξουμε ένα νέο αποθετήριο επιλέγουμε "New Project" -> "Create Blank Project". Στα πεδία επιλέγουμε το namespace, το όνομα και το visibility του project. Εφόσον θα κάνουμε git push κάποιο υφιστάμενο Git repo καλό και σωστό είναι να μην έχει README.

Για να κάνουμε git push τα περιεχόμενα από το τοπικό Git repository θα χρειαστεί να εκτελέσουμε τις εξής εντολές:

$ git remote add origin gitlab@repo.it.auth.gr:pkoro/shell-lesson-data.git
$ git push -u origin main
Enumerating objects: 23, done.
Counting objects: 100% (23/23), done.
Delta compression using up to 10 threads
Compressing objects: 100% (19/19), done.
Writing objects: 100% (23/23), 2.41 KiB | 2.41 MiB/s, done.
Total 23 (delta 4), reused 0 (delta 0), pack-reused 0
To repo.it.auth.gr:pkoro/shell-lesson-data.git
 * [new branch]      main -> main
branch 'main' set up to track 'origin/main'.

Αν έχουμε ήδη φτιάξει τοπικά και άλλα branches (πέρα από το main ή το master) μπορούμε να επιλέξουμε να τα κάνουμε push όλα μαζί με την εξής

$ git push -u origin --all

Στο γραφικό περιβάλλον του GitLab επιλέγοντας F5 θα πρέπει να βλέπουμε πλέον ότι τα περιεχόμενα του τοπικού μας repository έχουν αντιγραφεί στο remote repository στο GitLab. Από το μενού Code -> Commits στα αριστερά μπορούμε να δούμε και τα commits που έχουμε κάνει.


https vs ssh

Για να κάνουμε git push επιλέξαμε στα παραπάνω ως remote να ορίσουμε το ssh endpoint (gitlab@repo.it.auth.gr:pkoro/shell-lesson-data.git). Θα μπορούσαμε να ρυθμίσουμε εναλλακτικά το https (https://repo.it.auth.gr/pkoro/shell-lesson-data.git). Ένα αρνητικό που έχει το https σε σχέση με το ssh είναι ότι κάθε φορά μας ζητάει το username password.

Με την εντολή git remote -v βλέπουμε τι remotes έχουμε ορίσει:

$ git remote -v
origin	gitlab@repo.it.auth.gr:pkoro/shell-lesson-data.git (fetch)
origin	gitlab@repo.it.auth.gr:pkoro/shell-lesson-data.git (push)
Local (~/Desktop/shell-lesson-data) Remote pkoro/shell-lesson-data.git
maind37b3aea7569070a828a1a273d5153f1c5eebc0636
maind37b3aea7569070a828a1a273d5153f1c5eebc0636
Τι διαφορά έχει το git push από το git commit;

H git commit χρησιμοποιείται για να φτιάξουμε ένα commit (μιά εικόνα ή snapshot του κώδικά μας). H git push για να μεταφέρουμε όλο το περιεχόμενο προς ένα remote git repository (για να μοιράσουμε τον κώδικά μας δηλαδή όχι για να κάνουμε αλλαγές σε αυτόν).


Branching και αλλαγές

Εφόσον χρησιμοποιούμε ένα remote ως "source of truth" καλό είναι πλέον στο τοπικό μας repository να μην κάνουμε αλλαγές απευθείας στο mainmaster) branch αλλά να κάνουμε αλλαγές σε νέο branch. Για παράδειγμα αν έρθει ένας νέος φοιτητής και θέλουμε να τον προσθέσουμε στο πρόγραμμα είναι εύλογο να ξεκινήσουμε ανοίγωντας ένα νέο branch (π.χ. new_student) και κάνοντας αλλαγές σε αυτό:

$ git checkout -b new_student
Switched to a new branch 'new_student'

Έπειτα κάνουμε τις αλλαγές μας και όταν είμαστε έτοιμοι:

$ git commit -m "Add new student"
[new_student 02c79ab] Add new student
 2 files changed, 5 insertions(+), 4 deletions(-)
Local (~/Desktop/shell-lesson-data) Remote pkoro/shell-lesson-data.git
mainnew_studentd37b3aea7569070a828a1a273d5153f1c5eebc063602c79ab
maind37b3aea7569070a828a1a273d5153f1c5eebc0636

Για να περαστεί η αλλαγή και στο remote θα πρέπει να κάνουμε git push το νέο branch:

$ git push -u origin new_student
Enumerating objects: 9, done.
Counting objects: 100% (9/9), done.
Delta compression using up to 10 threads
Compressing objects: 100% (5/5), done.
Writing objects: 100% (5/5), 512 bytes | 512.00 KiB/s, done.
Total 5 (delta 3), reused 0 (delta 0), pack-reused 0
remote: 
remote: To create a merge request for new_student, visit:
remote:   https://repo.it.auth.gr/pkoro/shell-lesson-data/-/merge_requests/new?merge_request%5Bsource_branch%5D=new_student
remote: 
To repo.it.auth.gr:pkoro/shell-lesson-data.git
 * [new branch]      new_student -> new_student
branch 'new_student' set up to track 'origin/new_student'.
Local (~/Desktop/shell-lesson-data) Remote pkoro/shell-lesson-data.git
mainnew_studentd37b3aea7569070a828a1a273d5153f1c5eebc063602c79ab
mainnew_studentd37b3aea7569070a828a1a273d5153f1c5eebc063602c79ab

Ανοίγωντας το URL που μας επιστρέφει το GitLab σε ένα browser μας δίνεται η επιλογή να ανοίξουμε ένα "Merge Request".

Στο "Merge Request" καλό και χρήσιμο είναι να βάζουμε καλή περιγραφή σε όλα τα πεδία (Subject και Body) ώστε αυτός που θα το διαβάσει (και ενδεχομένως θα χρειαστεί να κάνει review τις αλλαγές) να έχει μιά καλή αντίληψη του τι περιμένει να δει.

Εφόσον οι αλλαγές γίνουν approve και merge η εικόνα των δύο repositories είναι η εξής:

Local (~/Desktop/shell-lesson-data) Remote pkoro/shell-lesson-data.git
mainnew_studentd37b3aea7569070a828a1a273d5153f1c5eebc063602c79ab
mainnew_studentd37b3aea7569070a828a1a273d5153f1c5eebc063602c79abea221955

Για να φέρουμε τις αλλαγές πίσω στο τοπικό repo θα χρειαστεί να κάνουμε git fetch το branch main από το remote repository και git merge στο τοπικό main repository.

$ git checkout main
Switched to branch 'main'
Your branch is up to date with 'origin/main'.
$ git fetch origin main
remote: Enumerating objects: 1, done.
remote: Counting objects: 100% (1/1), done.
remote: Total 1 (delta 0), reused 0 (delta 0), pack-reused 0
Unpacking objects: 100% (1/1), 262 bytes | 262.00 KiB/s, done.
From repo.it.auth.gr:pkoro/shell-lesson-data
 * branch            main       -> FETCH_HEAD
   ebc0636..ea22195  main       -> origin/main
$ git merge origin/main
Updating ebc0636..ea22195
Fast-forward
 semester_a/schedule.txt | 8 ++++----
 semester_a/students.txt | 1 +
 2 files changed, 5 insertions(+), 4 deletions(-)
Local (~/Desktop/shell-lesson-data) Remote pkoro/shell-lesson-data.git
mainnew_studentd37b3aea7569070a828a1a273d5153f1c5eebc063602c79abea221955
mainnew_studentd37b3aea7569070a828a1a273d5153f1c5eebc063602c79abea221955

Συνεργασία

Για να επιτρέψουμε σε ένα συνεργάτη μας να κάνει αλλαγές στο repo που φτιάξαμε στο GitLab θα πρέπει να τον προσθέσουμε στα μέλη (members) του project. Για τα επίπεδα πρόσβασης μας δίνονται διάφορες επιλογές (συνήθως -αν δεν είμαστε σίγουροι- επιλέγουμε Developer ρόλο για συνεργάτες μας που πρόκειται να κάνουν αλλαγές στον κώδικα).

Ο συνεργάτης μας (έστω ο χρήστης beta) έπειτα μπορεί να κάνει fork το remote repository στο προσωπικό του workspace και να αναλάβει να κάνει αλλαγές σε αυτό.

Local (~/Desktop/shell-lesson-data) Remote pkoro/shell-lesson-data.git Remote beta/shell-lesson-data.git
mainnew_studentd37b3aea7569070a828a1a273d5153f1c5eebc063602c79abea221955
mainnew_studentd37b3aea7569070a828a1a273d5153f1c5eebc063602c79abea221955
mainnew_studentd37b3aea7569070a828a1a273d5153f1c5eebc063602c79abea221955

Αφότου κάνει fork μπορεί να κάνει clone το repository στον υπολογιστή του ο χρήστης beta.

$ cd ~beta/Desktop
$ git clone gitlab@repo.it.auth.gr:beta/shell-lesson-data.git
Cloning into 'shell-lesson-data'...
remote: Enumerating objects: 29, done.
remote: Counting objects: 100% (29/29), done.
remote: Compressing objects: 100% (25/25), done.
remote: Total 29 (delta 8), reused 0 (delta 0), pack-reused 0
Receiving objects: 100% (29/29), done.
Resolving deltas: 100% (8/8), done.
Local (~/Desktop/shell-lesson-data) Remote pkoro/shell-lesson-data.git Remote beta/shell-lesson-data.git Local (~beta/shell-lesson-data)
mainnew_studentd37b3aea7569070a828a1a273d5153f1c5eebc063602c79abea221955
mainnew_studentd37b3aea7569070a828a1a273d5153f1c5eebc063602c79abea221955
mainnew_studentd37b3aea7569070a828a1a273d5153f1c5eebc063602c79abea221955
mainnew_studentd37b3aea7569070a828a1a273d5153f1c5eebc063602c79abea221955

Κατά "τα γνωστά" ο χρήστης beta κάνει κάποιες αλλαγές:

$ git checkout -b update_my_schedule
$ # edit semester_a/schedule.txt
$ git status
On branch update_my_schedule
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
	modified:   semester_a/schedule.txt

no changes added to commit (use "git add" and/or "git commit -a")
$ git add semester_a/schedule.txt
git commit -m "Updated my schedule"
[update_my_schedule 3a581f4] Updated my schedule
 1 file changed, 2 insertions(+), 2 deletions(-)
Local (~/Desktop/shell-lesson-data) Remote pkoro/shell-lesson-data.git Remote beta/shell-lesson-data.git Local (~beta/shell-lesson-data)
mainnew_studentd37b3aea7569070a828a1a273d5153f1c5eebc063602c79abea221955
mainnew_studentd37b3aea7569070a828a1a273d5153f1c5eebc063602c79abea221955
mainnew_studentd37b3aea7569070a828a1a273d5153f1c5eebc063602c79abea221955
mainnew_studentupdate_my_scheduled37b3aea7569070a828a1a273d5153f1c5eebc063602c79abea2219553a581f4

Έπειτα θα κάνει git push τις αλλαγές του στο remote του (επίσης "κατά τα γνωστά"):

$ git push -u origin update_my_schedule
Enumerating objects: 7, done.
Counting objects: 100% (7/7), done.
Delta compression using up to 10 threads
Compressing objects: 100% (4/4), done.
Writing objects: 100% (4/4), 431 bytes | 431.00 KiB/s, done.
Total 4 (delta 2), reused 0 (delta 0), pack-reused 0
remote: 
remote: To create a merge request for update_my_schedule, visit:
remote:   https://repo.it.auth.gr/beta/shell-lesson-data/-/merge_requests/new?merge_request%5Bsource_branch%5D=update_my_schedule
remote: 
To repo.it.auth.gr:beta/shell-lesson-data.git
 * [new branch]      update_my_schedule -> update_my_schedule
branch 'update_my_schedule' set up to track 'origin/update_my_schedule'.
Local (~/Desktop/shell-lesson-data) Remote pkoro/shell-lesson-data.git Remote beta/shell-lesson-data.git Local (~beta/shell-lesson-data)
mainnew_studentd37b3aea7569070a828a1a273d5153f1c5eebc063602c79abea221955
mainnew_studentd37b3aea7569070a828a1a273d5153f1c5eebc063602c79abea221955
mainnew_studentupdate_my_scheduled37b3aea7569070a828a1a273d5153f1c5eebc063602c79abea2219553a581f4
mainnew_studentupdate_my_scheduled37b3aea7569070a828a1a273d5153f1c5eebc063602c79abea2219553a581f4

Το GitLab (όπως και το GitHub) δίνει τη δυνατότητα ένα Merge Request να γίνει από ένα remote προς ένα άλλο. Άρα εφόσον το "source of truth" είναι το pkoro/shell-lesson-data το Merge Request θα πρέπει να γίνει προς αυτό το remote και συγκεκριμένα προς το main branch. Αφότου γίνει merge η εικόνα των repositories είναι αυτή:

Local (~/Desktop/shell-lesson-data) Remote pkoro/shell-lesson-data.git Remote beta/shell-lesson-data.git Local (~beta/shell-lesson-data)
mainnew_studentd37b3aea7569070a828a1a273d5153f1c5eebc063602c79abea221955
mainnew_studentupdate_my_scheduled37b3aea7569070a828a1a273d5153f1c5eebc063602c79abea2219553a581f4cd9dd462
mainnew_studentupdate_my_scheduled37b3aea7569070a828a1a273d5153f1c5eebc063602c79abea2219553a581f4
mainnew_studentupdate_my_scheduled37b3aea7569070a828a1a273d5153f1c5eebc063602c79abea2219553a581f4

Συγχρονισμός

Ο συνεργάτης beta προκειμένου να κάνει git fetch και git merge τις αλλαγές από το remote pkoro/shell-lesson-data repository θα χρειαστεί να το ορίσει ως νέο remote. Κατά σύμβαση αυτό το remote που έχει το ρόλο "source of truth" το ονομάζουμε upstream.

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →
~beta/Desktop/shell-lesson-data

$ git remote add upstream gitlab@repo.it.auth.gr:pkoro/shell-lesson-data.git
$ git remote -v
origin	gitlab@repo.it.auth.gr:beta/shell-lesson-data.git (fetch)
origin	gitlab@repo.it.auth.gr:beta/shell-lesson-data.git (push)
upstream	gitlab@repo.it.auth.gr:pkoro/shell-lesson-data.git (fetch)
upstream	gitlab@repo.it.auth.gr:pkoro/shell-lesson-data.git (push)

Προκειμένου να "συγχρονίσει" πλέον τις αλλαγές οι git fetch και git merge θα συνταχθούν ως εξής:

$ git checkout main
$ git fetch upstream main
remote: Enumerating objects: 1, done.
remote: Counting objects: 100% (1/1), done.
remote: Total 1 (delta 0), reused 0 (delta 0), pack-reused 0
Unpacking objects: 100% (1/1), 270 bytes | 270.00 KiB/s, done.
From repo.it.auth.gr:pkoro/shell-lesson-data
 * branch            main       -> FETCH_HEAD
 * [new branch]      main       -> upstream/main
$ git merge upstream/main
Updating ea22195..cd9dd46
Fast-forward
 semester_a/schedule.txt | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
Local (~/Desktop/shell-lesson-data) Remote pkoro/shell-lesson-data.git Remote beta/shell-lesson-data.git Local (~beta/shell-lesson-data)
mainnew_studentd37b3aea7569070a828a1a273d5153f1c5eebc063602c79abea221955
mainnew_studentupdate_my_scheduled37b3aea7569070a828a1a273d5153f1c5eebc063602c79abea2219553a581f4cd9dd462
mainnew_studentupdate_my_scheduled37b3aea7569070a828a1a273d5153f1c5eebc063602c79abea2219553a581f4
mainnew_studentupdate_my_scheduled37b3aea7569070a828a1a273d5153f1c5eebc063602c79abea2219553a581f4cd9dd462

Git conflicts (and how to resolve them)

Έστω ότι παράλληλα με την αλλαγή στο πρόγραμμα του χρήστη beta ο χρήστης pkoro έκανε επίσης κάποια αλλαγή (π.χ. στις ώρες του χρήστη testakos)

$ git checkout -b testakos
$ # edit semester_a/schedule.txt
$ git add semester_a/schedule.txt
$ git commit -m "Update schedule for testakos user"
[testakos 282dbef] Update schedule for testakos user
 1 file changed, 1 insertion(+), 1 deletion(-)
Local (~/Desktop/shell-lesson-data) Remote pkoro/shell-lesson-data.git Remote beta/shell-lesson-data.git Local (~beta/shell-lesson-data)
mainnew_studenttestakosd37b3aea7569070a828a1a273d5153f1c5eebc063602c79abea221955282dbef
mainnew_studentupdate_my_scheduled37b3aea7569070a828a1a273d5153f1c5eebc063602c79abea2219553a581f4cd9dd462
mainnew_studentupdate_my_scheduled37b3aea7569070a828a1a273d5153f1c5eebc063602c79abea2219553a581f4
mainnew_studentupdate_my_scheduled37b3aea7569070a828a1a273d5153f1c5eebc063602c79abea2219553a581f4cd9dd462

$ git push -u origin testakos
Local (~/Desktop/shell-lesson-data) Remote pkoro/shell-lesson-data.git Remote beta/shell-lesson-data.git Local (~beta/shell-lesson-data)
mainnew_studenttestakosd37b3aea7569070a828a1a273d5153f1c5eebc063602c79abea221955282dbef
mainnew_studentupdate_my_scheduletestakosd37b3aea7569070a828a1a273d5153f1c5eebc063602c79abea2219553a581f4cd9dd462282dbef
mainnew_studentupdate_my_scheduled37b3aea7569070a828a1a273d5153f1c5eebc063602c79abea2219553a581f4
mainnew_studentupdate_my_scheduled37b3aea7569070a828a1a273d5153f1c5eebc063602c79abea2219553a581f4cd9dd462

Καθώς έχει γίνει αλλαγή στην ίδια γραμμή από το Merge Request και commit που προηγήθηκε το GitLab μας ειδοποιεί ότι η νέα αλλαγή δεν μπορεί να περαστεί διότι υπάρχει conflict.

image

Για να δούμε εποπτικά που υπάρχει το πρόβλημα μπορούμε να επιλέξουμε το κουμπί "Resolve conflicts"

image

Βλέπουμε ότι η δική μας αλλαγή (our changes) είναι η αφαίρεση του χρήστη testakos από το πρόγραμμα της Τρίτης. Η αλλαγή που έχει κάνει ο άλλος developer (their changes) είναι η προσθήκη του χρήστη beta στο πρόγραμμα της Τετάρτης.

Από το γραφικό περιβάλλον μας δίνεται η επιλογή να επιλέξουμε μία από τις δύο αλλά εμείς θα θέλαμε και τις δύο να τις συμπεριλάβουμε. Αυτό μπορεί να γίνει είτε επιλέγοντας στο γραφικό περιβάλλον το κουμπί "Edit Inline" είτε Locally στο τοπικό Git repo. Το GitLab μας δίνει οδηγίες για το δεύτερο αν στην προηγούμενη σελίδα επιλέξουμε "Resolve locally".

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →
Resolve locally με git rebase

$ git checkout main
Switched to branch 'main'
Your branch is up to date with 'origin/main'.
$ git fetch origin main
remote: Enumerating objects: 8, done.
remote: Counting objects: 100% (8/8), done.
remote: Compressing objects: 100% (5/5), done.
remote: Total 5 (delta 3), reused 0 (delta 0), pack-reused 0
Unpacking objects: 100% (5/5), 544 bytes | 181.00 KiB/s, done.
From repo.it.auth.gr:pkoro/shell-lesson-data
 * branch            main       -> FETCH_HEAD
   ea22195..cd9dd46  main       -> origin/main
$ git merge origin/main
Updating ea22195..cd9dd46
Fast-forward
 semester_a/schedule.txt | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
Local (~/Desktop/shell-lesson-data) Remote pkoro/shell-lesson-data.git
mainnew_studentupdate_my_scheduletestakosd37b3aea7569070a828a1a273d5153f1c5eebc063602c79abea221955282dbef3a581f4cd9dd462
mainnew_studentupdate_my_scheduletestakosd37b3aea7569070a828a1a273d5153f1c5eebc063602c79abea2219553a581f4cd9dd462282dbef

Διαδικασία rebase

$ git checkout testakos
Switched to branch 'testakos'
Your branch is up to date with 'origin/testakos'.
$ git rebase main
Auto-merging semester_a/schedule.txt
CONFLICT (content): Merge conflict in semester_a/schedule.txt
error: could not apply 282dbef... Update schedule for testakos user
hint: Resolve all conflicts manually, mark them as resolved with
hint: "git add/rm <conflicted_files>", then run "git rebase --continue".
hint: You can instead skip this commit: run "git rebase --skip".
hint: To abort and get back to the state before "git rebase", run "git rebase --abort".
Could not apply 282dbef... Update schedule for testakos user
$ git status
interactive rebase in progress; onto cd9dd46
Last command done (1 command done):
   pick 282dbef Update schedule for testakos user
No commands remaining.
You are currently rebasing branch 'testakos' on 'cd9dd46'.
  (fix conflicts and then run "git rebase --continue")
  (use "git rebase --skip" to skip this patch)
  (use "git rebase --abort" to check out the original branch)

Unmerged paths:
  (use "git restore --staged <file>..." to unstage)
  (use "git add <file>..." to mark resolution)
	both modified:   semester_a/schedule.txt

no changes added to commit (use "git add" and/or "git commit -a")
$ # Edit semester_a/schedule.txt and fix conflicts
$ git status
interactive rebase in progress; onto cd9dd46
Last command done (1 command done):
   pick 282dbef Update schedule for testakos user
No commands remaining.
You are currently rebasing branch 'testakos' on 'cd9dd46'.
  (fix conflicts and then run "git rebase --continue")
  (use "git rebase --skip" to skip this patch)
  (use "git rebase --abort" to check out the original branch)

Unmerged paths:
  (use "git restore --staged <file>..." to unstage)
  (use "git add <file>..." to mark resolution)
	both modified:   semester_a/schedule.txt

no changes added to commit (use "git add" and/or "git commit -a")
$ git add semester_a/schedule.txt
$ git rebase --continue # On the EDITOR that pops up change the commit message if you'd like or just exit
[detached HEAD 910a2f2] Update schedule for testakos user
 1 file changed, 1 insertion(+), 1 deletion(-)
Successfully rebased and updated refs/heads/testakos.
$ git status
On branch testakos
Your branch and 'origin/testakos' have diverged,
and have 3 and 1 different commits each, respectively.
  (use "git pull" to merge the remote branch into yours)

nothing to commit, working tree clean
Local (~/Desktop/shell-lesson-data) Remote pkoro/shell-lesson-data.git
mainnew_studentupdate_my_scheduletestakosd37b3aea7569070a828a1a273d5153f1c5eebc063602c79abea2219553a581f4cd9dd462910a2f2
mainnew_studentupdate_my_scheduletestakosd37b3aea7569070a828a1a273d5153f1c5eebc063602c79abea2219553a581f4cd9dd462282dbef

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →
Προσοχή στο ότι πλέον έχει αλλάξει το commit id. Αυτό που έχουμε τοπικά δεν είναι το ίδιο με αυτό που υπάρχει από το git push που προηγήθηκε στο remote. Για το λόγο αυτό η git push πλέον θα αποτύχει:

$ git push -u origin testakos
To repo.it.auth.gr:pkoro/shell-lesson-data.git
 ! [rejected]        testakos -> testakos (non-fast-forward)
error: failed to push some refs to 'repo.it.auth.gr:pkoro/shell-lesson-data.git'
hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart. Integrate the remote changes (e.g.
hint: 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.

Προκειμένου να κάνουμε push θα χρειαστεί να χρησιμοποιήσουμε το -f--force):

$ git push -f -u origin testakos
Enumerating objects: 7, done.
Counting objects: 100% (7/7), done.
Delta compression using up to 10 threads
Compressing objects: 100% (4/4), done.
Writing objects: 100% (4/4), 434 bytes | 434.00 KiB/s, done.
Total 4 (delta 2), reused 0 (delta 0), pack-reused 0
remote: 
remote: View merge request for testakos:
remote:   https://repo.it.auth.gr/pkoro/shell-lesson-data/-/merge_requests/3
remote: 
To repo.it.auth.gr:pkoro/shell-lesson-data.git
 + 282dbef...910a2f2 testakos -> testakos (forced update)
branch 'testakos' set up to track 'origin/testakos'.
Local (~/Desktop/shell-lesson-data) Remote pkoro/shell-lesson-data.git
mainnew_studentupdate_my_scheduletestakosd37b3aea7569070a828a1a273d5153f1c5eebc063602c79abea2219553a581f4cd9dd462910a2f2
mainnew_studentupdate_my_scheduletestakosd37b3aea7569070a828a1a273d5153f1c5eebc063602c79abea2219553a581f4cd9dd462910a2f2

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →
voilà
Το Merge Request μετά το "force push" είναι "mergable".
Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →