This shows you the differences between two versions of the page.
uso:cursuri:curs-05 [2022/10/03 21:18] sergiu.weisz |
uso:cursuri:curs-05 [2022/10/31 22:54] (current) sergiu.weisz |
||
---|---|---|---|
Line 1: | Line 1: | ||
- | ====== Curs 05 - Dezvoltarea programelor ======= | + | ====== Curs 05 - Interfața în linia de comandă ======= |
- | * [[https://drive.google.com/file/d/1BmuPPAptcKqqHbRtw7oYPNMOtHnuXZoi/view?usp=sharing | Slide-uri curs]] | + | * [[https://docs.google.com/presentation/d/1Dk4gnDZd3TefbtyG3i4qSoO7YoXZOP5q/edit?usp=sharing&ouid=108131427433094834232&rtpof=true&sd=true|Slide-uri curs]] |
- | * [[https://drive.google.com/file/d/1i6mDB0NqS9toWXe1Mfml_GJGLM-ms7eG/view?usp=sharing | Handout 3on1 and notes space]] | + | * **Cuvinte cheie**: interfață, GUI, CLI, prompt, comandă, argumente, command completion, istoric de comenzi, shell, terminal, documentare, libreadline, ''>'', ''<'', ''&'', ''|'', ''||'', ''&&'', '';'', ''%%"%%'', %%'%%, ''\'', ''$'', one liner, variabile, variabile de mediu, escaping, expandare, globbing |
- | * [[https://drive.google.com/file/d/1-PMESQDyFS9-3F1sC1gRXHbFLo1lVNtt/view?usp=sharing | Handout 6on1]] | + | |
- | * **Cuvinte cheie**: cod sursă, cod mașină, editor, IDE, pachet Software, fișier executabil, fișier obiect, compilare, linking, interpretoare, limbajul C, gcc, modularizare, sisteme de build, make, Makefile, git | + | |
* **Suport de curs** | * **Suport de curs** | ||
- | * [[https://github.com/systems-cs-pub-ro/carte-uso/releases | Utilizarea sistemelor de operare]] | + | * [[https://github.com/systems-cs-pub-ro/carte-uso/releases | Utilizarea sistemelor de operare]] |
- | * Secțiunea 6 - Dezvoltarea programelor | + | * Secțiunea 7 - Interfata in linia de comanda |
- | ====== Demo ======= | + | <HTML> |
+ | <center> | ||
+ | <iframe src="https://docs.google.com/presentation/d/e/2PACX-1vSgCQrUZIoJoRMvmJZZzYrrPCpdW2Id2_Rjv0rec-IKsKx0tkpXc8jnPS5NLCSq1g/embed?start=false&loop=false&delayms=3000" frameborder="0" width="480" height="389" allowfullscreen="true" mozallowfullscreen="true" webkitallowfullscreen="true"></iframe> | ||
+ | </center> | ||
+ | </HTML> | ||
+ | /* | ||
- | ==== Comanda dpkg ==== | + | ====== Curs 05 - Administrarea sistemului de fișiere ======= |
- | * Utilitarul dpkg este un manager de pachete pentru sisteme bazate pe Debian (ex. Ubuntu), care poate realiza mai multe acțiuni. | + | |
- | * Pentru simpla instalare a unui pachet, folosim opțiunea -i, alături de numele fișierului „.deb”, descărcat anterior (sau calea către acest fișier, dacă ne aflăm într-un folder diferit): | + | |
- | <code> | + | * [[http://elf.cs.pub.ro/uso/res/cursuri/curs-05/curs-05-handout.pdf|Slide-uri curs]] |
- | student@uso:~$ sudo dpkg -i google-chrome-stable_current_amd64.deb | + | * [[http://elf.cs.pub.ro/uso/res/cursuri/curs-05/curs-05-handout-4on1-notes.pdf|Handout 4on1 and notes space]] |
- | Selecting previously unselected package google-chrome-stable. | + | * [[http://elf.cs.pub.ro/uso/res/cursuri/curs-05/curs-05-handout-8on1.pdf|Handout 8on1]] |
- | (Reading database ... 196951 files and directories currently installed.) | + | * **Cuvinte cheie**: sistem de fișiere, fizic și virtual, disc, partiție, partiționare, MBR, GPT, formatare, ''fdisk'', ''mkfs'', montare, ''mount'', ''umount'', link-uri, dispozitive, permisiuni, //user, group, others//, //read, write, execute//, ''chmod'', ''chown'' |
- | Preparing to unpack google-chrome-stable_current_amd64.deb ... | + | * **Suport de curs** |
- | Unpacking google-chrome-stable (86.0.4240.111-1) ... | + | * [[http://books.google.com/books?id=_JFGzyRxQGcC | Introducere în sisteme de operare]] |
- | Setting up google-chrome-stable (86.0.4240.111-1) ... | + | * [[http://books.google.com/books?id=_JFGzyRxQGcC&pg=PA69 | Capitolul 4 - Sisteme de fișiere]] |
- | update-alternatives: using /usr/bin/google-chrome-stable to provide /usr/bin/x-www-browser (x-www-browser) in auto mode | + | * Secțiunile 4.3.7, 4.5, 4.7, 4.8 |
- | update-alternatives: using /usr/bin/google-chrome-stable to provide /usr/bin/gnome-www-browser (gnome-www-browser) in auto mode | + | |
- | update-alternatives: using /usr/bin/google-chrome-stable to provide /usr/bin/google-chrome (google-chrome) in auto mode | + | |
- | Processing triggers for gnome-menus (3.13.3-11ubuntu1.1) ... | + | |
- | Processing triggers for desktop-file-utils (0.23-1ubuntu3.18.04.1) ... | + | |
- | Processing triggers for mime-support (3.60ubuntu1) ... | + | |
- | Processing triggers for man-db (2.8.3-2) ... | + | |
- | </code> | + | |
- | <note> În cazul în care pe sistemul nostru este deja instalată o versiune mai veche a pachetului, dpkg creează un back up al vechilor fișiere, astfel încât să poată păstra versiunea inițială dacă apar probleme la noua instalare. </note> | + | <HTML> |
+ | <center> | ||
+ | <iframe src="https://docs.google.com/viewer?url=http://elf.cs.pub.ro/uso/res/cursuri/curs-05/curs-05-handout.pdf&embedded=true" width="600" height="480" style="border: none;"> | ||
+ | </iframe> | ||
+ | </center> | ||
+ | </HTML> | ||
- | * Pentru a șterge un pachet instalat, folosim opțiunea -r: | + | */ |
- | <code> | ||
- | sudo dpkg -r google-chrome-stable | ||
- | (Reading database ... 197063 files and directories currently installed.) | ||
- | Removing google-chrome-stable (86.0.4240.111-1) ... | ||
- | </code> | ||
- | În cazul ștergerii, trebuie să folosim ca parametru al comenzii numele pachetului instalat, nu numele fișierului „.deb” folosit pentru instalare. | + | ===== Demo ===== |
- | * Anumite fișiere de configurare ar putea rămâne în sistem după simpla ștergere cu -r, deoarece au fost create separat de scripturi de configurare. Dacă vrem să fim siguri că și acestea sunt șterse, putem folosi opțiunea dpkg -P (purge) | + | ==== Variabila PATH ==== |
- | <code> | + | Dacă rulați în terminal comanda: |
- | student@uso:~$ sudo dpkg -P google-chrome-stable | + | <code>echo $PATH</code> |
- | (Reading database ... 197063 files and directories currently installed.) | + | Veți vedea o listă de directoare de genul: |
- | Removing google-chrome-stable (86.0.4240.111-1) ... | + | <code>/home/student/.local/share/umake/bin:/home/student/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/usr/lib/jvm/java-8-oracle/bin:/usr/lib/jvm/java-8-oracle/db/bin:/usr/lib/jvm/java-8-oracle/jre/bin</code> |
- | ... | + | Dacă puneți un executabil în oricare din aceste directoare, nu mai este nevoie să setați calea către executabil și puteți să îl rulați direct ca o comandă, folosind numele executabilului. |
- | Purging configuration files for google-chrome-stable (86.0.4240.111-1) ... | + | |
- | </code> | + | |
- | * Tot dpkg ne oferă posibilitatea de a lista toate pachetele din sistem, alături de versiune, tipul arhitecturii și o scurtă descriere, cu opțiunea -l: | + | ==== Globbing ==== |
<code> | <code> | ||
- | student@uso:~$ dpkg -l | + | student@myPc:~/USO/test$ ls |
- | Name Version Architecture Description | + | endian.c endian.o hello hello.c Makefile socket.c struct.c struct.o |
- | +++-==========================================-===============================================-============-=============================================================================== | + | student@myPc:~/USO/test$ ls *.c |
- | ii accountsservice 0.6.45-1ubuntu1 amd64 query and manipulate user account information | + | endian.c hello.c socket.c struct.c |
- | ii acl 2.2.52-3build1 amd64 Access control list utilities | + | student@myPc:~/USO/test$ ls end?an.c |
- | ii acpi-support 0.142 amd64 scripts for handling many ACPI events | + | endian.c |
- | ii acpid 1:2.0.28-1ubuntu1 amd64 Advanced Configuration and Power Interface event daemon | + | student@myPc:~/USO/test$ ls [a-s]*.c |
- | ii adduser 3.116ubuntu1 all add and remove users and groups | + | endian.c hello.c socket.c struct.c |
- | ........... | + | student@myPc:~/USO/test$ ls *.{c,o} |
+ | endian.c endian.o hello.c socket.c struct.c struct.o | ||
</code> | </code> | ||
+ | Mai sus avem câteva exemple de rulare a comenzii ls impreună cu expresii regulate. | ||
- | * Dacă ne interesează să verificăm dacă un anumit pachet este deja instalat, putem folosi opțiunea -s, care ne va afișa statusul pachetului (installed / uninstalled) și o serie mai largă de informații legate de acesta: | + | Ce reprezintă fiecare operator? |
+ | * ***:** 0 sau mai multe caractere | ||
+ | * **+:** 1 sau mai multe caractere | ||
+ | * **?:** 0 sau 1 caracter | ||
+ | * **[a-s]:** orice literă de la "a" la "s" | ||
+ | * **[A-Za-z]:** orice literă, mică sau mare | ||
+ | * **{c,o}:** c sau o | ||
+ | |||
+ | ==== Escapări ==== | ||
<code> | <code> | ||
- | student@uso:~$ dpkg -s zsh | + | student@myPc:~/USO/test$ ls -l |
- | Package: zsh | + | total 0 |
- | Status: install ok installed | + | -rw-r--r-- 1 student student 0 nov 8 17:41 'ana are mere.txt' |
- | Priority: optional | + | -rw-r--r-- 1 student student 0 nov 8 17:18 endian.c |
- | Section: shells | + | -rw-r--r-- 1 student student 0 nov 8 17:18 endian.o |
- | Installed-Size: 2070 | + | -rw-r--r-- 1 student student 0 nov 8 17:00 hello |
- | Maintainer: Ubuntu Developers ubuntu-devel-discuss@lists.ubuntu.com | + | -rw-r--r-- 1 student student 0 nov 8 17:00 hello.c |
- | ....... | + | -rw-r--r-- 1 student student 0 nov 8 17:00 Makefile |
+ | -rw-r--r-- 1 student student 0 nov 8 17:01 socket.c | ||
+ | -rw-r--r-- 1 student student 0 nov 8 17:00 struct.c | ||
+ | -rw-r--r-- 1 student student 0 nov 8 17:01 struct.o | ||
+ | student@myPc:~/USO/test$ ls ana are mere.txt | ||
+ | ls: cannot access 'ana': No such file or directory | ||
+ | ls: cannot access 'are': No such file or directory | ||
+ | ls: cannot access 'mere.txt': No such file or directory | ||
+ | student@myPc:~/USO/test$ la "ana are mere.txt" | ||
+ | 'ana are mere.txt' | ||
+ | student@myPc:~/USO/test$ ls 'ana are mere.txt' | ||
+ | 'ana are mere.txt' | ||
+ | student@myPc:~/USO/test$ ls ana\ are\ mere.txt | ||
+ | 'ana are mere.txt' | ||
</code> | </code> | ||
- | |||
- | |||
- | ==== gcc (compilarea programelor) ==== | ||
- | |||
- | * GNU Compiler Collection este un compilator pentru C/C++, adică un program ce traduce codul nostru sursă în cod mașină, păstrat într-un fișier executabil și care va putea fi rulat pe procesor. | ||
- | * Pentru a compila un fișier de tip cod sursă, putem folosi comanda gcc însoțită de numele sursei: | ||
<code> | <code> | ||
- | student@uso:~/demos$ gcc hello_world.c | + | student@myPc:~/USO/test$ echo "Hello World" |
- | student@uso:~/demos$ ls | + | Hello World |
- | a.out hello_world.c | + | student@myPc:~/USO/test$ echo Hello World |
- | student@uso:~/demos$ file a.out | + | Hello World |
- | a.out: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/l, for GNU/Linux 3.2.0, BuildID[sha1]=ddbe5634d0b0da5b4eab5d27d6b77236d7a90f7b, not stripped | + | student@myPc:~/USO/test$ echo "Hello \"World\"" |
+ | Hello "World" | ||
+ | student@myPc:~/USO/test$ echo "Hello "World"" | ||
+ | Hello World | ||
</code> | </code> | ||
- | |||
- | Observăm că după rularea comenzii este creat fișierul a.out de tip „ELF 64-bit shared object”, adică un fișier executabil ce va putea fi rulat. | ||
- | |||
- | * Dacă dorim ca executabilul rezultat în urma compilării să aibă un anumit nume, folosim opțiunea -o: | ||
<code> | <code> | ||
- | student@uso:~/demos$ gcc hello_world.c -o hello | + | student@myPc:~/USO/test$ echo \" |
- | student@uso:~/demos$ ls | + | " |
- | hello hello_world.c | + | student@myPc:~/USO/test$ echo "" |
- | </code> | + | |
- | * Prin utilizarea a diferitelor opțiuni, putem opri procesul de compilare după fiecare pas descris în curs și obținem astfel fișierul obținut la fiecare etapă a compilării. | + | student@myPc:~/USO/test$ echo \"\" |
- | Cu opțiunea -E, rezultatul este codul rezultat după etapa de preprocesare. Acest cod este afișat la ieșirea standard, însă poate fi redirectat într-un fișier cu extensia „.i” (această extensie indică faptul că fișierul nu mai trebuie să treacă prin preprocesare). | + | "" |
- | + | ||
- | <code> | + | |
- | student@uso:~/demos$ gcc -E hello_world.c > hello_world.i | + | |
- | student@uso:~/demos$ file hello_world.i | + | |
- | hello_world.i: C source, ASCII text | + | |
</code> | </code> | ||
- | Pentru a obține fișierul în limbaj de asamblare rezultat în urma compilării, folosim opțiunea -S (în aces caz, codul în limbaj de asamblare este salvat direct într-un fișier cu extensia „.s”): | + | <note>Pentru ca un caracter special să fie utilizat ca un caracter obișnuit în bash, el trebuie să fie escapat.</note> |
- | <code> | + | ==== Expandări ==== |
- | student@uso:~/demos$ gcc -S hello_world.c | + | |
- | student@uso:~/demos$ file hello_world.s | + | |
- | hello_world.s: assembler source, ASCII text | + | |
- | </code> | + | |
- | + | ||
- | După ce codul a fost tradus din limbaj de asamblare în cod mașină, putem opri procesul înaintea etapei de link-editare, folosind opțiunea „-c”. Rezultatul va fi un fișier cu extensia „.o” ce conține cod mașină, fără a fi linkat încă cu bibliotecile necesare. | + | |
<code> | <code> | ||
- | student@uso:~/demos$ gcc -c hello_world.c | + | student@myPc:~/USO/test/files$ touch $(seq -f "file-%02g.txt" 1 20) |
- | student@uso:~/demos$ file hello_world.o | + | student@myPc:~/USO/test/files$ touch file.txt |
- | hello_world.o: ELF 64-bit LSB relocatable, x86-64, version 1 (SYSV), not stripped | + | student@myPc:~/USO/test/files$ ls |
+ | file-01.txt file-04.txt file-07.txt file-10.txt file-13.txt file-16.txt file-19.txt | ||
+ | file-02.txt file-05.txt file-08.txt file-11.txt file-14.txt file-17.txt file-20.txt | ||
+ | file-03.txt file-06.txt file-09.txt file-12.txt file-15.txt file-18.txt file.txt | ||
+ | student@myPc:~/USO/test/files$ rm -rf $(seq -f "file-%02g.txt" 1 20) | ||
+ | student@myPc:~/USO/test/files$ ls | ||
+ | file.txt | ||
</code> | </code> | ||
- | |||
- | * În general, programele pe care le dezvoltăm sunt prea complexe pentru a fi scrise într-un singur fișier, motiv pentru care ne dorim să realizăm compilarea din mai multe surse. Pentru a ilustra modul de lucru, vom crea un program care să realizeze operațiile de adunare și scădere a 2 numere întregi. Vom folosi fișierul sursă „operations.c” pentru a implementa cele 2 funcții și fișierul „main.c” pentru a apela aceste funcții. | ||
- | |||
<code> | <code> | ||
- | operations.c | + | student@myPc:~/USO/test/files$ a=6 |
- | int addition(int a, int b) { | + | student@myPc:~/USO/test/files$ echo a |
- | return a + b; | + | a |
- | } | + | student@myPc:~/USO/test/files$ echo $a |
- | int substraction(int a, int b) { | + | 6 |
- | return a - b; | + | student@myPc:~/USO/test/files$ echo $((a)) |
- | } | + | 6 |
- | </code> | + | student@myPc:~/USO/test/files$ a++ |
- | Pentru a putea apela funcțiile din „operations.c” în „main.c”, va trebui să creăm un fișier de tip header, în acest caz „operations.h”, pe care să-l includem la începutul fișierului main și care să conțină doar antetele funcțiilor respective. | + | Command 'a++' not found, did you mean: |
- | <code> | + | command 'a+' from deb aplus-fsf |
- | Operations.h | + | command 'g++' from deb g++ |
- | int addition(int a, int b); | + | command 'c++' from deb g++ |
- | int substraction(int a, int b); | + | command 'c++' from deb clang |
- | Main.c | + | command 'c++' from deb libc++-helpers |
- | #include <stdio.h> | + | command 'c++' from deb pentium-builder |
- | #include "operations.h" | + | command 'ac++' from deb aspectc++ |
- | int main() { | + | command 'ag++' from deb aspectc++ |
- | int a = 3, b = 2; | + | |
- | printf("Suma este: %d\n", addition(a, b)); | + | |
- | printf("Diferenta este: %d\n", substraction(a, b)); | + | |
- | return 0; | + | |
- | } | + | |
- | </code> | + | |
- | <note>Dacă am include „operations.c” ar apărea o eroare la compilare, din cauza faptului că ar apărea câte 2 definiții ale funcțiilor, atât în „operations.c”, cât și în „main.c”. Folosind un header, în „main.c” vom include doar antetele, compilatorul știind astfel că aceste funcții există, urmând să găsească definițiile lor în alt fișier. | + | Try: sudo apt install <deb name> |
- | </note> | + | |
- | <note> La includerea antetelor definite de noi, numele antetului se pune între „”, nu între <>, ca în cazul „stdio.h”. gcc ne va permite să compilăm ambele surse și să obținem un singur executabil final.</note> | + | student@myPc:~/USO/test/files$ ((a++)) |
- | <code> | + | student@myPc:~/USO/test/files$ echo $a |
- | student@uso:~/demos$ gcc -o operations operations.c main.c | + | 7 |
- | student@uso:~/demos$ ./operations | + | student@myPc:~/USO/test/files$ b=$((a-4)) |
- | Suma este: 5 | + | student@myPc:~/USO/test/files$ echo $b |
- | Diferenta este: 1 | + | 3 |
</code> | </code> | ||
- | ==== Make ==== | ||
- | * Atunci când lucrăm la aplicații complexe, care implică un număr mare de fișiere sursă, headere etc., procesul de build devine greoi dacă este făcut „manual” (de ex. prin comanda gcc la fiecare re-compilare a codului sursă, când apar modificări). Pentru a automatiza acest proces, putem folosi utilitarul make. | + | ==== cat și redirectarea ==== |
- | * Comanda make caută în directorul curent fișiere numite Makefile. Un fișier Makefile conține una sau mai multe reguli, adică nume atribuite unor comenzi. Comanda make fără argumente execută prima regulă din Makefile, iar dacă dorim să rulăm o anumită regulă, folosim „make <nume regulă>”. | + | |
- | * Pentru programul cu operațiile aritmetice, putem scrie următorul Makefile, conținând regula build care se va ocupa de compilare: | + | |
<code> | <code> | ||
- | Makefile | + | student@myPc:~/USO/test/files$ echo Ana are mere > test.txt |
- | build : | + | student@myPc:~/USO/test/files$ cat test.txt |
- | gcc -o operations operations.c main.c | + | Ana are mere |
+ | student@myPc:~/USO/test/files$ echo "Ana are mere 2" >> test.txt | ||
+ | student@myPc:~/USO/test/files$ cat test.txt | ||
+ | Ana are mere | ||
+ | Ana are mere 2 | ||
</code> | </code> | ||
+ | |||
<code> | <code> | ||
- | student@uso:~/demos$ make | + | student@myPc:~/USO/test/files$ id student &> /dev/null && echo "da" || echo "nu" |
- | gcc -o operations operations.c main.c | + | da |
- | student@uso:~/demos$ ./operations | + | student@myPc:~/USO/test/files$ id student &> /dev/null && echo "da" || echo "nu" |
- | Suma este: 5 | + | nu |
- | Diferenta este: 1 | + | |
</code> | </code> | ||
- | * Tot în Makefile putem defini mai multe reguli, între care putem stabili anumite dependențe. Pe scurt, rularea unei reguli va depinde de existența unuia sau mai multor fișiere. Dacă fișierele respective există în directorul curent, regula este rulată, dacă nu, se caută în Makefile o altă regulă cu numele respectivului fișier și se rulează mai întâi aceasta (sau se continuă lanțul dependețelor). | ||
- | <code> | + | ==== tac, rev și nl ==== |
- | Makefile | + | |
- | build : operations.o | + | |
- | gcc -o operations operations.o main.c | + | |
- | operations.o: | + | |
- | gcc -c operations.c | + | |
- | clean: | + | |
- | rm operations | + | |
- | </code> | + | |
<code> | <code> | ||
- | student@uso:~/demos$ make | + | student@myPc:~/USO/test/files$ echo "Ana are mere 2" >> test.txt |
- | gcc -c operations.c | + | student@myPc:~/USO/test/files$ ls |
- | gcc -o operations operations.o main.c | + | test.txt |
- | student@uso:~/demos$ ./operations | + | student@myPc:~/USO/test/files$ tac test.txt |
- | Suma este: 5 | + | Ana are mere 2 |
- | Diferenta este: 1 | + | Ana are mere |
- | student@uso:~/demos$ make clean | + | student@myPc:~/USO/test/files$ cat test.txt |
- | rm operations | + | Ana are mere |
- | student@uso:~/demos$ ls | + | Ana are mere 2 |
- | Makefile main.c operations.c operations.h operations.o | + | student@myPc:~/USO/test/files$ rev test.txt |
+ | erem era anA | ||
+ | 2 erem era anA | ||
+ | student@myPc:~/USO/test/files$ nl test.txt | ||
+ | 1 Ana are mere | ||
+ | 2 Ana are mere 2 | ||
</code> | </code> | ||
- | Mai sus, regula build depinde de un fișier de tip obiect numit „operations.o”. Deoarece acesta nu există încă în director, se rulează regula cu numele lui, care generează fișierul prin compilarea sursei „operations.c”, iar apoi se revine la regula build. De asemenea, am adăugat regula clean, folosită pentru a șterge executabilul când am încheiat o sesiune de testare. | + | <note> |
+ | * cat → afișeaza conținutul fișierului | ||
+ | * tac → afișeaza conținutul fișierului în ordinea inversă a liniilor | ||
+ | * rev → afișeaza liniile inversate (primul element de pe linie devine ultimul) | ||
+ | * nl → afișeaza numărul liniei | ||
+ | </note> | ||
- | + | ==== head și tail ==== | |
- | ==== Git ==== | + | |
- | + | ||
- | * Aproape toate aplicațiile complexe sunt dezvoltate în echipe, fapt care poate face organizarea și structurarea proiectului destul de complicată. Ne vom dori adesea ca anumite feature-uri să fie dezvoltate și testate separat și doar apoi integrate în proiectul final. De asemenea, apar situații când ne dorim să ne putem întoarce la un stadiu anterior al proiectului. Git este un sistem de versionare a codului ce rezolvă astfel de probleme, iar în continuare vom prezenta câteva comenzi de bază. | + | |
- | * Un proiect este păstrat într-un repository (repo), în cazul lucrului în echipă fiind vorba despre un repository remote. Pentru a crea o clonă locală a unui repo, folosim comanda git clone, însoțită de numele repository-ului. Această comandă creează pe sistemul local un folder cu numele repository-ului, care va conține atât fișierele propriu zise, cât și fișierele utilizate de git în realizarea versionării. | + | |
<code> | <code> | ||
- | student@uso:~/demos$ git clone https://github.com/systems-cs-pub-ro/uso | + | student@myPc:~/USO/test/files$ cat test.txt |
- | Cloning into 'uso'... | + | Ana are mere |
- | remote: Enumerating objects: 150, done. | + | Ana are mere 2 |
- | remote: Counting objects: 100% (150/150), done. | + | Ana are mere 3 |
- | remote: Compressing objects: 100% (115/115), done. | + | Maria are pere |
- | remote: Total 2198 (delta 31), reused 138 (delta 19), pack-reused 2048 | + | Ana are mere |
- | Receiving objects: 100% (2198/2198), 118.28 MiB | 5.20 MiB/s, done. | + | student@myPc:~/USO/test/files$ cat test.txt | head -n 2 |
- | Resolving deltas: 100% (1016/1016), done. | + | Ana are mere |
- | student@uso:~/demos$ cd uso | + | Ana are mere 2 |
- | student@uso:~/demos/uso$ ls -a | + | student@myPc:~/USO/test/files$ cat test.txt | tail -n 2 |
- | . .git 'TW Warhammer' lab03 lab05 lab10 tema1 tema3 | + | Maria are pere |
- | .. README.md lab02 lab04 lab09 lab12 tema2 tema4 | + | Ana are mere |
</code> | </code> | ||
- | * La creare, un repository are doar branch-ul master, care conține în general versiunea stabilă a proiectului. Atunci când vrem să ne aducem contribuția, ne creăm un branch distinct pornind de la master sau de la un alt branch deja existent. Astfel, putem să facem orice modificare, fără a afecta branch-ul de la care am pornit. Comanda git checkout -b <nume branch> va crea un branch nou și ne va muta automat pe acesta (git status afișează numele branch-ului curent și situația modificărilor aduse). Imediat după creare, stadiul proiectului din noul branch va fi identic cu cel înregistrat în branch-ul de la care am pornit. | + | <note> |
+ | * head -n 2 → afișează primele 2 linii din fisier | ||
+ | * tail -n 2 → afișează ultimele 2 linii din fisier | ||
+ | </note> | ||
+ | |||
+ | ==== sort, uniq și wc ==== | ||
<code> | <code> | ||
- | student@uso:~/demos/uso$ git checkout -b cool_feature | + | student@myPc:~/USO/test/files$ cat test.txt |
- | Switched to a new branch 'cool_feature' | + | Ana are mere |
- | student@uso:~/demos/uso$ git status | + | Ana are mere 2 |
- | On branch cool_feature | + | Ana are mere 3 |
- | nothing to commit, working tree clean | + | Maria are pere |
+ | Ana are mere | ||
+ | student@myPc:~/USO/test/files$ sort test.txt | ||
+ | Ana are mere | ||
+ | Ana are mere | ||
+ | Ana are mere 2 | ||
+ | Ana are mere 3 | ||
+ | Maria are pere | ||
+ | student@myPc:~/USO/test/files$ sort -r -n test.txt | ||
+ | Maria are pere | ||
+ | Ana are mere 3 | ||
+ | Ana are mere 2 | ||
+ | Ana are mere | ||
+ | Ana are mere | ||
+ | student@myPc:~/USO/test/files$ wc test.txt | ||
+ | 5 17 71 test.txt | ||
+ | student@myPc:~/USO/test/files$ wc -c test.txt | ||
+ | 71 test.txt | ||
+ | student@myPc:~/USO/test/files$ wc -l test.txt | ||
+ | 5 test.txt | ||
+ | student@myPc:~/USO/test/files$ sort test.txt > test22.txt | ||
+ | student@myPc:~/USO/test/files$ cat test22.txt | ||
+ | Ana are mere | ||
+ | Ana are mere | ||
+ | Ana are mere 2 | ||
+ | Ana are mere 3 | ||
+ | Maria are pere | ||
+ | student@myPc:~/USO/test/files$ uniq test22.txt | ||
+ | Ana are mere | ||
+ | Ana are mere 2 | ||
+ | Ana are mere 3 | ||
+ | Maria are pere | ||
</code> | </code> | ||
- | * Conceptul de salvare al unui anumit stadiu al proiectului poate fi asociat cu crearea unui commit. | + | <note> |
+ | * sort → sortează intrările | ||
+ | * uniq → elimină duplicatele din fișier | ||
+ | * wc → numară elementele din fisier | ||
+ | </note> | ||
- | După simpla adăugare a unui nou fișier (sau după modificarea unui fișier existent), git ne va semnala că statusul acestuia este untracked. Folosind comanda git add, adăugăm fișierul respectiv pe lista fișierelor ce conțin update-uri pe care vrem să le includem în următorul commit. | + | ==== cut și tr ==== |
- | <code> | + | <code>student@myPc:~/USO/test$ ls -l |
- | student@uso:~/demos/uso$ echo "cool_feature" > cool_feature.txt | + | total 4 |
- | student@uso:~/demos/uso$ git status | + | -rw-r--r-- 1 student student 0 nov 8 17:41 'ana are mere.txt' |
- | On branch cool_feature | + | -rw-r--r-- 1 student student 0 nov 8 17:18 endian.c |
- | Untracked files: | + | -rw-r--r-- 1 student student 0 nov 8 17:18 endian.o |
- | (use "git add <file>..." to include in what will be committed) | + | drwxr-xr-x 2 student student 4096 nov 8 18:36 files |
- | cool_feature.txt | + | -rw-r--r-- 1 student student 0 nov 8 17:00 hello |
- | nothing added to commit but untracked files present (use "git add" to track) | + | -rw-r--r-- 1 student student 0 nov 8 17:00 hello.c |
- | student@uso:~/demos/uso$ git add cool_feature.txt | + | -rw-r--r-- 1 student student 0 nov 8 17:00 Makefile |
- | student@uso:~/demos/uso$ git status | + | -rw-r--r-- 1 student student 0 nov 8 17:01 socket.c |
- | On branch cool_feature | + | -rw-r--r-- 1 student student 0 nov 8 17:00 struct.c |
- | Changes to be committed: | + | -rw-r--r-- 1 student student 0 nov 8 17:01 struct.o |
- | (use "git reset HEAD <file>..." to unstage) | + | student@myPc:~/USO/test$ ls -l | tr -d '.' |
- | new file: cool_feature.txt | + | total 4 |
+ | -rw-r--r-- 1 student student 0 nov 8 17:41 ana are meretxt | ||
+ | -rw-r--r-- 1 student student 0 nov 8 17:18 endianc | ||
+ | -rw-r--r-- 1 student student 0 nov 8 17:18 endiano | ||
+ | drwxr-xr-x 2 student student 4096 nov 8 18:36 files | ||
+ | -rw-r--r-- 1 student student 0 nov 8 17:00 hello | ||
+ | -rw-r--r-- 1 student student 0 nov 8 17:00 helloc | ||
+ | -rw-r--r-- 1 student student 0 nov 8 17:00 Makefile | ||
+ | -rw-r--r-- 1 student student 0 nov 8 17:01 socketc | ||
+ | -rw-r--r-- 1 student student 0 nov 8 17:00 structc | ||
+ | -rw-r--r-- 1 student student 0 nov 8 17:01 structo | ||
+ | student@myPc:~/USO/test$ ls -l | tr -d ' ' | ||
+ | total4 | ||
+ | -rw-r--r--1studentstudent0nov817:41anaaremere.txt | ||
+ | -rw-r--r--1studentstudent0nov817:18endian.c | ||
+ | -rw-r--r--1studentstudent0nov817:18endian.o | ||
+ | drwxr-xr-x2studentstudent4096nov818:36files | ||
+ | -rw-r--r--1studentstudent0nov817:00hello | ||
+ | -rw-r--r--1studentstudent0nov817:00hello.c | ||
+ | -rw-r--r--1studentstudent0nov817:00Makefile | ||
+ | -rw-r--r--1studentstudent0nov817:01socket.c | ||
+ | -rw-r--r--1studentstudent0nov817:00struct.c | ||
+ | -rw-r--r--1studentstudent0nov817:01struct.o | ||
+ | student@myPc:~/USO/test$ ls -l | tr -d '-' | ||
+ | total 4 | ||
+ | rwrr 1 student student 0 nov 8 17:41 ana are mere.txt | ||
+ | rwrr 1 student student 0 nov 8 17:18 endian.c | ||
+ | rwrr 1 student student 0 nov 8 17:18 endian.o | ||
+ | drwxrxrx 2 student student 4096 nov 8 18:36 files | ||
+ | rwrr 1 student student 0 nov 8 17:00 hello | ||
+ | rwrr 1 student student 0 nov 8 17:00 hello.c | ||
+ | rwrr 1 student student 0 nov 8 17:00 Makefile | ||
+ | rwrr 1 student student 0 nov 8 17:01 socket.c | ||
+ | rwrr 1 student student 0 nov 8 17:00 struct.c | ||
+ | rwrr 1 student student 0 nov 8 17:01 struct.o | ||
</code> | </code> | ||
- | După ce am adăugat toate fișierele pe care dorim să le folosim, comanda git commit -m va salva un snapshot al fazei curente a proiectului nostru, alături de un mesaj sugestiv transmis ca argument. Commit-ul va fi înregistrat alături de metadatele sale (data și ora, branch-ul, mesajul) în istoricul repo-ului. Pentru a vizualiza ulterior acest istoric, putem folosi comanda git log. | + | <code>student@myPc:~/USO/test/files$ cat test.txt |
- | + | Ana are mere | |
- | <code> | + | Ana are mere 2 |
- | student@uso:~/demos/uso$ git commit -m "Create cool feature" | + | Ana are mere 3 |
- | [cool_feature 0bfd61e] Add cool feature | + | Maria are pere |
- | 1 file changed, 1 insertion(+) | + | Ana are mere |
- | create mode 100644 cool_feature.txt | + | student@myPc:~/USO/test/files$ cat test.txt | cut -d' ' -f1 |
- | student@uso:~/demos/uso$ git log | + | Ana |
- | commit 0bfd61efa5778e62d090da43a1def9f96f5e1930 (HEAD -> cool_feature) | + | Ana |
- | Author: Student USO VM User <student@stud.acs.upb.ro> | + | Ana |
- | Date: Sun Oct 25 15:46:53 2020 +0200 | + | Maria |
- | Add cool feature | + | Ana |
- | ...... | + | student@myPc:~/USO/test/files$ cat test.txt | cut -d' ' -f1,3 |
+ | Ana mere | ||
+ | Ana mere | ||
+ | Ana mere | ||
+ | Maria pere | ||
+ | Ana mere | ||
</code> | </code> | ||
- | <note>Unul dintre motivele pentru care folosim mai întâi git add și apoi git commit este că uneori vom avea mai multe fișiere modificate și vom dori să le grupăm în commit-uri într-un mod relevant (1 commit – o funcționalitate adăugată/un bug rezolvat), astfel încât să păstrăm un istoric relevant al proiectului.</note> | + | <note> |
- | + | * tr → elimină caractere | |
- | * Atunci când considerăm că modificările pot fi integrate în versiunea finală a proiectului, realizăm operația de merge, prin care integrăm modificările aflate momentan doar pe branch-ul nostru în branch-ul master. | + | * cut → afișeaza doar liniile pe care le dăm de la tastatură |
- | + | </note> | |
- | <code> | + | |
- | student@uso:~/demos/uso$ git checkout master | + | |
- | Switched to branch 'master' | + | |
- | Your branch is up to date with 'origin/master'. | + | |
- | student@uso:~/demos/uso$ ls | + | |
- | README.md lab02 lab04 lab09 lab12 tema2 tema4 | + | |
- | 'TW Warhammer' lab03 lab05 lab10 tema1 tema3 | + | |
- | student@uso:~/demos/uso$ git merge master cool_feature | + | |
- | Updating 0b8c9aa..0bfd61e | + | |
- | Fast-forward | + | |
- | cool_feature.txt | 1 + | + | |
- | 1 file changed, 1 insertion(+) | + | |
- | create mode 100644 cool_feature.txt | + | |
- | student@uso:~/demos/uso$ ls | + | |
- | README.md cool_feature.txt lab03 lab05 lab10 tema1 tema3 | + | |
- | 'TW Warhammer' lab02 lab04 lab09 lab12 tema2 tema4 | + | |
- | </code> | + | |
- | + | ||
- | * În cazul în care lucrăm cu un repository remote, comanda git push rulată dintr-un branch al repository-ului local va crea în repository-ul „părinte” o copie a acestui branch, care va conține istoricul commit-urilor de pe branch-ul local. În acest caz, procesul de merge cu branch-ul master va fi probabil gestionat prin platforma online care găzduiește proiectul (ex. Github). | + | |
- | + | ||
- | Pentru a înțelege mai bine modul de lucru cu git, puteți parcurge următorul tutorial: https://gitimmersion.com/ | + |