Version Control Systems Mercurial SCM Μανώλης Κιαγιάς
Version Control Systems Καλύπτουν δύο βασικές ανάγκες: Τήρηση πολλαπλών εκδόσεων των αρχείων πηγαίου κώδικα ενός Έργου με ευκολία Τη δυνατότητα συνεργασίας πολλών ατόμων στο ίδιο έργο με ταυτόχρονη διασφάλιση του κώδικα και του ιστορικού Το Έργο μπορεί να είναι πηγαίος κώδικας κάποιας γλώσσας, τεκμηρίωση, βιβλίο, LaTeX κλπ. Για την κάλυψη των παραπάνω, κάθε σύστημα VCS παρέχει μια σειρά από βασικές λειτουργίες, αρκετά όμοιες, αλλά και προχωρημένες δυνατότητες 2
Version Control Systems Σκοπός κάθε σωστού VCS πρέπει να είναι: Να κάνει τη ζωή του χρήστη πιο εύκολη Να επικεντρώνεται ο προγραμματιστής στη δουλειά του και όχι στο VCS Να απαλείψει το γνωστό άγχος Άλλαξα τον κώδικα, ο νέος δεν παίζει, δεν έχω backup το παλιό! Πως λειτουργεί; Πως λειτουργεί; Σε γενικές γραμμές κάθε VCS αποθηκεύει όλες τις εκδόσεις του ίδιου αρχείου ως μια σειρά από αρχεία διαφορών με τα οποία μετά μπορεί να συναρμολογήσει οποιαδήποτε παλιά έκδοση ζητήσουμε. Ο ακριβής τρόπος αποθήκευσης εξαρτάται από την υλοποίηση. 3
Version Control Systems Πρόσθετες δυνατότητες Εύρεση διαφορών μεταξύ δύο οποιαδήποτε εκδόσεων Δημιουργία διάφορων γραμμών ανάπτυξης (branches) Ετικέττες (tags) μπορούν να σηματοδοτούν την κατάσταση ενός Έργου σε μια χρονική στιγμή. Π.χ. Αν έχουμε το source repository του FreeBSD μπορούμε να ζητήσουμε τα αρχεία με την ετικέττα 7.2-RELEASE για να κάνουμε build τη συγκεκριμένη έκδοση (καλές 3:00) Τήρηση ιστορικού που περιγράφει κάθε αλλαγή και ποιος την έκανε (Να βρούμε σε ποιον θα πούμε Μπράβο ή Εσύ φταις! - αν και το δεύτερο διορθώνεται εύκολα) 4
Version Control Systems Ιστορικά Στοιχεία RCS το πρώτο και πολύ απλό CVS Θέλω ένα RCS με καταλόγους SVN Θέλω ένα CVS εξελιγμένο Distributed Repositories: Git, Mercurial (η νέα τάση) Υπάρχουν παραπάνω από 20 Open Source VCS 5
Version Control Systems Βασικές Λειτουργίες Checkout Να πάρουμε ένα αντίγραφο εργασίας των αρχείων Checkin ή Commit Να καταχωρήσουμε ως νέα έκδοση μια αλλαγή που κάναμε στην περιοχή εργασίας μας Add / Remove Να θέσουμε ένα νέο αρχείο στον έλεγχο του repository ή να διαγράψουμε ένα αρχείο από αυτό. Diff Να δούμε τις διαφορές μεταξύ δύο οποιονδήποτε εκδόσεων Log Να δούμε το ιστορικό των commits και λεπτομέρειες για το καθένα Status Να δούμε ποια αρχεία έχουν αλλάξει / προστεθεί στην περιοχή εργασίας Merge Ανάμειξη αλλαγών που έχουν γίνει από διαφορετικά άτομα στο ίδιο αρχείο 6
Version Control Systems Δύο Βασικές Τεχνοτροπίες: Κεντρικό Σύστημα: CVS, SVN κ.α. Κατανεμημένο Σύστημα: Mercurial, Git, κ.α. Το κατανεμημένο είναι η νέα τάση, και σίγουρα έχει αρκετά πλεονεκτήματα. 7
Version Control Systems Κεντρικό Μοντέλο: Checkout Update Κεντρικό Repository Merging Conflicts Commit Περιοχή Εργασίας Περιοχή Εργασίας Περιοχή Εργασίας Γιώργος Γιάννης Ούρσουλα 8
Version Control Systems Κατανεμημένο Μοντέλο: Γιώργος Repository Γιάννης Repository Περιοχή Εργασίας Push Pull Περιοχή Εργασίας Commit Checkout Update Ούρσουλα Repository Commit Checkout Update Περιοχή Εργασίας Commit Checkout Update 9
Πλεονεκτήματα Κατανεμημένων VCS Έχουμε πάντα όλο το ιστορικό αλλά και τις εκδόσεις μαζί μας Μπορούμε να δουλέψουμε offline έχοντας συνέχεια τη σιγουριά που προσφέρει το VCS Άτομα που δεν ανήκουν επίσημα στο Έργο μας μπορούν εύκολα να συνεισφέρουν διατηρώντας το δικό τους αντίγραφο και στέλνοντας μας bundles ή και παραδοσιακά diffs. Μπορούμε επίσης να κάνουμε εμείς pull. Εύκολη διαδικασία branching / merging Έχει και μειονεκτήματα. Μπορείτε να σκεφτείτε μερικά; 10
Mercurial SCM Γραμμένο σε Python Κατανεμημένο Σύστημα Φτιαγμένο για ευκολία σε συνεργατικά Έργα και ταχύτητα στην εκτέλεση των λειτουργιών Πολύ εύκολο branching / tagging Πλήθος από πρόσθετα extensions 3 way merge και δυνατότητα χρήσης εξωτερικών προγραμμάτων Δυνατότητα Web interface μέσω apache/cgi ή και άμεσα για γρήγορο sharing Μπορεί να αποθηκεύσει και binary αρχεία χωρίς να χρειάζεται ειδικές ρυθμίσεις και χωρίς να τα καταστρέφει (ακούς CVS;) 11
Mercurial SCM - Εγκατάσταση Το mercurial διατίθεται στα repos των περισσότερων διανομών: Για χρήστες Debian/Ubuntu: aptitude install mercurial Για χρήστες Fedora/Redhat/Centos: yum install mercurial Για χρήστες FreeBSD: cd /usr/ports/devel/mercurial && make install clean Για χρήστη OpenSUSE: zypper install mercurial 12
Ξεκινώντας με το Mercurial Step 0 Τα mercurial αποτελείται από: Την περιοχή του repository (Mercurial store) Την περιοχή εργασίας (work area) Τα changesets. Δημιουργούνται κάθε φορά που γίνεται commit Για να ξεκινήσουμε το workshop, κάντε login: ssh chanialug@saturn Password: abcd1234#$ Δημιουργήστε ένα κατάλογο με το όνομα σας και ένα κατάλογο repo1 mkdir -p <onoma-sas>/repo1 13
Δημιουργώντας Mercurial Repo Step 1 Στον κατάλογο που μόλις φτιάξατε: cd <onoma-sas>/repo1 hg init Τo repository δημιουργείται μέσα στον κατάλογο.hg vim.hg/hgrc Βάλτε τις παρακάτω γραμμές για να εμφανίζεται σωστά το όνομα σας στα commit messages: [ui] username = Joe User <joe@kolokithi.com> 14
Το Πρώτο Αρχείο Step 2 Δημιουργήστε το πρώτο μας αρχείο, hello.c: vim hello.c Γράψτε ένα κλασικό Hello World: # include <stdio.h> int main() { printf( Hello Mercurial!\n ); return 0; } 15
Το Πρώτο Αρχείο Step 3 Το repository δεν ξέρει ακόμα τι να το κάνει: hg status? hello.c Ας το προσθέσουμε: hg add hello.c Το μήνυμα τώρα αλλάζει σε: hg status A hello.c 16
Το Πρώτο Commit Step 4 Ας κάνουμε το πρώτο commit hg commit Θα ανοίξει ο προεπιλεγμένος editor για να γράψουμε το commit message: Added initial revision of hello.c HG: Enter commit message. Lines beginning with 'HG:' are removed. HG: -- HG: user: Joe User <joe@kolokithi.com> HG: branch 'default' HG: added hello.c 17
Καταγραφή Step 5 Ας δούμε τι έχει καταγραφεί στο log: hg log Βλέπουμε τις λεπτομέρειες: changeset: 0:70ecab6961de tag: tip user: Joe User <joe@kolokithi.com> date: Fri Jun 05 10:21:56 2009 +0300 summary: Added initial revision of hello.c 18
Δεύτερο Commit Step 6 Προσθέστε μια ακόμα γραμμή στο hello.c: # include <stdio.h> int main() { printf( Hello Mercurial!\n ); printf( Goodbye source chaos!\n ); return 0; } Κάντε ξανά commit hg commit 19
Το Log Ξανά Step 7 Ας δούμε το log: hg log Θα μοιάζει με: changeset: 1:9b86d807364d tag: tip user: Joe User <joe@kolokithi.com> date: Fri Jun 05 10:39:15 2009 +0300 summary: Second version of hello.c changeset: 0:70ecab6961de user: Joe User <joe@kolokithi.com> date: Fri Jun 05 10:21:56 2009 +0300 summary: Added initial revision of hello.c 20
Το Πρώτο Diff Step 8 Ας κάνουμε ένα diff των εκδόσεων: hg diff -r 0:1 ή Θα hg μοιάζει diff -r με: 0:tip diff -r 70ecab6961de -r 9b86d807364d hello.c --- a/hello.c Fri Jun 05 10:21:56 2009 +0300 +++ b/hello.c Fri Jun 05 10:39:15 2009 +0300 @@ -3,5 +3,6 @@ int main() { printf("hello Mercurial!\n"); + printf("goodbye source chaos!\n"); return 0; } 21
Κλωνοποίηση Step 9 Είναι πολύ απλό να κάνετε ένα κλώνο του repo1 στο repo2 cd.. hg clone repo1 repo2 updating working directory 1 files updated, 0 files merged, 0 files removed, 0 files unresolved Μπείτε ξανά στο repo1, κάντε μια αλλαγή στο hello.c και κάντε την commit. Έπειτα μπείτε στο repo2 και κάντε την pull: cd repo1 vim hello.c (αλλάξτε ότι θέλετε) hg commit cd../repo2 hg pull../repo1 22
Pull και Push Step 10 Μετά το pull θα δείτε: pulling from../repo1/ searching for changes adding changesets adding manifests adding file changes added 1 changesets with 1 changes to 1 files (run 'hg update' to get a working copy) Το αρχείο στην περιοχή εργασίας δεν έχει αλλάξει! Πρέπει να εκτελέσετε hg update: hg update 1 files updated, 0 files merged, 0 files removed, 0 files unresolved 23
Μerging Step 11 Τι γίνεται αν κάνουμε μια αλλαγή στο repo1, μια στο repo2 στο ίδιο αρχείο, τις κάνουμε commit και κάνουμε pull? Δοκιμάστε το. Αλλάξτε μια γραμμή στο hello.c στο repo1, μια άλλη γραμμή στο repo2, κάντε commit στο ένα και στο άλλο και κάντε στο repo2 pull από το repo1. (repo2) hg pull../repo1 pulling from /home/sonic/repo1 searching for changes adding changesets adding manifests adding file changes added 1 changesets with 1 changes to 1 files (+1 heads) (run 'hg heads' to see heads, 'hg merge' to merge) 24
Merging Step 12 Όταν συμβεί αυτό, δημιουργούνται δύο heads: 25
Merging Step 13 Όταν ένα parent έχει δυο children, έχει δημιουργηθεί ένα branch. Μπορούμε τώρα να κάνουμε merge: hg merge merging hello.c 0 files updated, 1 files merged, 0 files removed, 0 files unresolved (branch merge, don't forget to commit) hg commit Κοιτάξτε τώρα το hello.c. Οι αλλαγές έχουν συγχωνευθεί. Άσκηση: Κάντε τώρα στο repo1 pull από το repo2 26
Conflicts Step 14 Δοκιμάστε αυτό: Αλλάξτε μια γραμμή στο hello.c στο repo1, την ίδια γραμμή στο repo2, κάντε commit στο ένα και στο άλλο και κάντε στο repo2 pull από το repo1. (repo2) hg pull../repo1 (messages ommitted) hg merge merging hello.c 3 files to edit Σε debian ubuntu (σε γραφικό περιβάλλον) ανοίγει το gvimdiff. Εδώ θα δούμε ένα χειροκίνητο merge Σημείωση: Το τι ακριβώς γίνεται είναι κάτι που ρυθμίζεται στο hgrc (θα το ψάξετε γιατί δεν τελειώνουμε ποτέ) 27
Τagging Step 15 Μπορούμε να δώσουμε ένα συγκεκριμένο όνομα σε ένα revision: hg tag -r 0 FirstVersion hg tags Μπορούμε να γυρίσουμε την περιοχή εργασίας σε αυτό το revision χρησιμοποιώντας το tag: hg update -r FirstVersion Το οποίο θα ήταν εδώ το ίδιο με: hg update -r 0 28
HTTP Serving Step 16 Μπορούμε να σηκώσουμε ένα γρήγορο Web interface γράφοντας απλώς: hg serve Από προεπιλογή, η πόρτα είναι η 8000 (αλλά μπορεί να αλλάξει). Αν το μηχάνημα μας έχει IP 192.168.0.15, μπορούμε να δούμε τη σελίδα από ένα άλλο μηχάνημα με http://192.168.0.15:8000 (Γράψτε το στο Firefox. Κεκτημένη ταχύτητα, όλα σε terminal τα δείχνω) 29
Wrap It Up - Step 17 Στο σημείο αυτό είναι ασφαλές να υποθέσουμε ότι έχει συμβεί κάτι από τα παρακάτω: Έχουν φύγει οι μισοί (και βάλε) από την αίθουσα Ο Ηλίας έχει βάλει Ubuntu, ο Χρήστος OpenSuse Ένας πύραυλος με το όνομα μου έχει φύγει από το Κολυμπάρι Τι δεν καλύψαμε (εννοείτε πολλά, αλλά...): Branching με την hg branch (χρήσιμο σε projects που έχουν διαφορετικές γραμμές ανάπτυξης) Ρυθμίσεις hgrc / extensions Περισσότερες πληροφορίες http://www.selenic.com/mercurial/wiki/understandingmercurial http://www.selenic.com/mercurial/wiki/tutorial http://people.freebsd.org/~keramida/hg-slides.pdf 30