Git: полное руководство

28 августа, 2020

Оглавление

Git – это распределенная система контроля версий и управления исходным кодом с упором на скорость. Первоначально Git был разработан и разработан Линусом Торвальдсом для разработки ядра Linux. Git – это бесплатное программное обеспечение, распространяемое в соответствии с условиями GNU General Public License версии 2. В этом руководстве объясняется, как использовать Git для управления версиями проекта в распределенной среде при разработке веб-приложений и приложений, не основанных на веб-технологиях.

Это руководство поможет новичкам изучить базовые функции системы контроля версий Git. После завершения этого руководства вы обнаружите, что обладаете умеренным опытом в использовании системы контроля версий Git, откуда вы сможете перейти на следующий уровень.

Мы предполагаем, что вы собираетесь использовать Git для обработки всех уровней Java и не-Java проектов. Так что будет хорошо, если у вас будет некоторое знакомство с жизненным циклом разработки программного обеспечения и практические знания по разработке веб-приложений и приложений, не основанных на Интернете.

Базовые концепции

Система контроля версий

Система контроля версий (VCS) – это программное обеспечение, которое помогает разработчикам программного обеспечения работать вместе и вести полную историю своей работы.

Ниже перечислены функции VCS –

  • Позволяет разработчикам работать одновременно.
  • Не позволяет перезаписывать изменения друг друга.
  • Ведет историю каждой версии.

Ниже приведены типы VCS –

  • Централизованная система контроля версий (CVCS).
  • Распределенная / децентрализованная система контроля версий (DVCS).

В этой главе мы сосредоточимся только на распределенной системе контроля версий и особенно на Git. Git подпадает под распределенную систему контроля версий.

Распределенная система контроля версий

Централизованная система контроля версий (CVCS) использует центральный сервер для хранения всех файлов и обеспечивает совместную работу команды. Но главный недостаток CVCS – это ее единственная точка отказа, то есть отказ центрального сервера. К сожалению, если центральный сервер выйдет из строя на час, то в течение этого часа никто вообще не сможет сотрудничать. И даже в худшем случае, если диск центрального сервера будет поврежден и надлежащая резервная копия не будет сделана, вы потеряете всю историю проекта. Здесь на сцену выходит распределенная система контроля версий (DVCS).

Клиенты DVCS не только проверяют последний снимок каталога, но также полностью зеркалируют репозиторий. Если сервер выходит из строя, то репозиторий с любого клиента можно скопировать обратно на сервер, чтобы восстановить его. Каждая выписка – это полная резервная копия репозитория. Git не полагается на центральный сервер, и поэтому вы можете выполнять множество операций, когда находитесь в автономном режиме. Вы можете фиксировать изменения, создавать ветки, просматривать журналы и выполнять другие операции в автономном режиме. Сетевое подключение требуется только для публикации ваших изменений и принятия последних изменений.

Преимущества Git

1. Бесплатный и открытый исходный код

Git выпускается под лицензией GPL с открытым исходным кодом. Он доступен бесплатно в Интернете. Вы можете использовать Git для управления проектами недвижимости, не платя ни копейки. Поскольку это открытый исходный код, вы можете загрузить его исходный код, а также внести изменения в соответствии с вашими требованиями.

2. Быстрый и маленький

Поскольку большинство операций выполняется локально, это дает огромное преимущество с точки зрения скорости. Git не полагается на центральный сервер; поэтому нет необходимости взаимодействовать с удаленным сервером для каждой операции. Основная часть Git написана на C, что позволяет избежать накладных расходов времени выполнения, связанных с другими языками высокого уровня. Хотя Git отражает весь репозиторий, размер данных на стороне клиента невелик. Это демонстрирует эффективность Git при сжатии и хранении данных на стороне клиента.

3. Неявное резервное копирование

Шансы на потерю данных очень редки, если их несколько копий. Данные, присутствующие на любой стороне клиента, отражают репозиторий, поэтому их можно использовать в случае сбоя или повреждения диска.

4. Безопасность

Git использует общую криптографическую хеш-функцию, называемую защищенной хеш-функцией (SHA1), для именования и идентификации объектов в своей базе данных. Каждый файл и фиксация проверяются и извлекаются по контрольной сумме во время проверки. Это означает, что невозможно изменить файл, дату, сообщение фиксации и любые другие данные из базы данных Git, не зная Git.

5. Нет необходимости в мощном оборудовании

В случае CVCS центральный сервер должен быть достаточно мощным, чтобы обслуживать запросы всей команды. Для небольших команд это не проблема, но по мере роста размера команды аппаратные ограничения сервера могут стать узким местом для производительности. В случае DVCS разработчики не взаимодействуют с сервером, если им не нужно отправлять или извлекать изменения. Вся тяжелая работа выполняется на стороне клиента, поэтому серверное оборудование действительно может быть очень простым.

6. Более легкое ветвление

CVCS использует дешевый механизм копирования. Если мы создадим новую ветвь, она скопирует все коды в новую ветку, поэтому это требует много времени и неэффективно. Кроме того, удаление и объединение ветвей в CVCS сложно и требует много времени. Но управлять ветками с помощью Git очень просто. Создание, удаление и объединение веток занимает всего несколько секунд.

Терминология DVCS

Локальный репозиторий

Каждый инструмент VCS предоставляет частное рабочее место в качестве рабочей копии. Разработчики вносят изменения на своем рабочем месте, и после фиксации эти изменения становятся частью репозитория. Git делает еще один шаг вперед, предоставляя им частную копию всего репозитория. Пользователи могут выполнять множество операций с этим репозиторием, например добавлять файл, удалять файл, переименовывать файл, перемещать файл, фиксировать изменения и многое другое.

Рабочий каталог и промежуточная область или индекс

Рабочий каталог – это место, где файлы извлекаются. В других CVCS разработчики обычно вносят изменения и фиксируют свои изменения непосредственно в репозитории. Но Git использует другую стратегию. Git не отслеживает каждый измененный файл. Каждый раз, когда вы фиксируете операцию, Git ищет файлы в промежуточной области. Только те файлы, которые присутствуют в промежуточной области, рассматриваются для фиксации, а не все измененные файлы.

Давайте посмотрим на основной рабочий процесс Git.

  1. Вы изменяете файл из рабочего каталога.
  2. Вы добавляете эти файлы в промежуточную область.
  3. Вы выполняете операцию фиксации, которая перемещает файлы из области подготовки. После операции push изменения навсегда сохраняются в репозитории Git.
Git Tutorial

Предположим, вы изменили два файла, а именно «sort.c» и «search.c», и вам нужно два разных коммита для каждой операции. Вы можете добавить один файл в промежуточную область и выполнить фиксацию. После первой фиксации повторите ту же процедуру для другого файла.

# First commit
[bash]$ git add sort.c

# adds file to the staging area
[bash]$ git commit –m “Added sort operation”

# Second commit
[bash]$ git add search.c

# adds file to the staging area
[bash]$ git commit –m “Added search operation”

Блобы(Blobs)

Блоб означает большой двоичный объект. Каждая версия файла представлена большим двоичным объектом. Большой двоичный объект содержит данные файла, но не содержит метаданных о файле. Это двоичный файл, и в базе данных Git он называется хеш-кодом SHA1 этого файла. В Git к файлам не обращаются по именам. Все адресовано по содержанию.

Древо(Trees)

Древо – это объект, представляющий каталог. Он содержит блобы, а также другие подкаталоги. Древо – это двоичный файл, в котором хранятся ссылки на большие двоичные объекты и деревья, которые также называются хешем SHA1 объекта древа.

Коммиты(Commits)

Коммит содержит текущее состояние репозитория. Коммит также называется хешем SHA1. Вы можете рассматривать объект фиксации как узел связанного списка. Каждый объект фиксации имеет указатель на родительский объект фиксации. От заданной фиксации вы можете вернуться назад, посмотрев на родительский указатель, чтобы просмотреть историю фиксации. Если у фиксации есть несколько родительских коммитов, то эта конкретная фиксация была создана путем слияния двух ветвей.

Ветви(Branches)

Ветви используются для создания еще одной линии развития. По умолчанию у Git есть основная ветка, такая же, как и в Subversion. Обычно ветка создается для работы над новой функцией. Как только функция завершена, она снова объединяется с основной веткой, и мы удаляем ветку. На каждую ветку ссылается HEAD, который указывает на последнюю фиксацию в ветке. Каждый раз, когда вы делаете коммит, HEAD обновляется последней фиксацией.

Теги(Tags)

Тег присваивает значимое имя определенной версии в репозитории. Теги очень похожи на ветки, но разница в том, что теги неизменяемы. Значит, тег – это ветка, которую никто не собирается изменять. После создания тега для конкретной фиксации, даже если вы создаете новую фиксацию, он не будет обновлен. Обычно разработчики создают теги для выпусков продуктов.

Клонировать(Clone)

Операция клонирования создает экземпляр репозитория. Операция клонирования не только проверяет рабочую копию, но также отражает весь репозиторий. Пользователи могут выполнять множество операций с этим локальным репозиторием. Единственный раз, когда в сеть включается, – это когда экземпляры репозитория синхронизируются.

Pull

Операция Pull копирует изменения из экземпляра удаленного репозитория в локальный. Операция Pull используется для синхронизации между двумя экземплярами репозитория. Это то же самое, что и операция обновления в Subversion.

Push

Операция push копирует изменения из экземпляра локального репозитория в удаленный. Это используется для постоянного хранения изменений в репозитории Git. Это то же самое, что и операция фиксации в Subversion.

HEAD

HEAD – это указатель, который всегда указывает на последнюю фиксацию в ветке. Каждый раз, когда вы делаете коммит, HEAD обновляется последней фиксацией. Головы веток хранятся в каталоге .git/refs/heads/

[CentOS]$ ls -1 .git/refs/heads/
master

[CentOS]$ cat .git/refs/heads/master
570837e7d58fa4bccd86cb575d884502188b0c49

Revision

Revision представляет собой версию исходного кода. Редакции в Git представлены коммитами. Эти коммиты идентифицируются безопасными хэшами SHA1.

URL

URL-адрес представляет собой расположение репозитория Git. URL-адрес Git хранится в файле конфигурации.

[tom@CentOS tom_repo]$ pwd
/home/tom/tom_repo

[tom@CentOS tom_repo]$ cat .git/config
[core]
repositoryformatversion = 0
filemode = true
bare = false
logallrefupdates = true
[remote "origin"]
url = gituser@git.server.com:project.git
fetch = +refs/heads/*:refs/remotes/origin/*

Настройка среды

Прежде чем вы сможете использовать Git, вам необходимо установить и внести некоторые базовые изменения конфигурации. Ниже приведены шаги по установке клиента Git в Ubuntu и Centos Linux.

Установка клиента Git

Если вы используете базовый дистрибутив Debian GNU/Linux, то команда apt-get сделает все необходимое.

[ubuntu ~]$ sudo apt-get install git-core
[sudo] password for ubuntu:

[ubuntu ~]$ git --version
git version 1.8.1.2

И если вы используете дистрибутив GNU / Linux на основе RPM, используйте команду yum, как указано.

[CentOS ~]$
su -
Password:

[CentOS ~]# yum -y install git-core

[CentOS ~]# git --version
git version 1.7.1

Настройка среды Git

Git предоставляет инструмент конфигурации git, который позволяет вам устанавливать переменные конфигурации. Git хранит все глобальные конфигурации в файле .gitconfig, который находится в вашем домашнем каталоге. Чтобы установить эти значения конфигурации как глобальные, добавьте параметр –global, и если вы опустите параметр –global, ваши конфигурации будут специфичными для текущего репозитория Git.

Вы также можете настроить общесистемную конфигурацию. Git хранит эти значения в файле /etc/gitconfig, который содержит конфигурацию для каждого пользователя и репозитория в системе. Чтобы установить эти значения, вы должны иметь права root и использовать параметр –system.

Когда приведенный выше код компилируется и выполняется, он дает следующий результат:

Установка имени пользователя

Эта информация используется Git для каждого commit.

[jerry@CentOS project]$ git config --global user.name "Jerry Mouse"

Установка идентификатора электронной почты

Эта информация используется Git для каждого commit.

[jerry@CentOS project]$ git config --global user.email "jerry@tutorialspoint.com"

Избегайте слияния коммитов для pulling

Вы делаете pull  последних изменений из удаленного репозитория, и если эти изменения расходятся, то по умолчанию Git создает коммиты слияния. Этого можно избежать с помощью следующих настроек.

jerry@CentOS project]$ git config --global branch.autosetuprebase always

Цветовое выделение

Следующие команды включают выделение цветом для Git в консоли.

[jerry@CentOS project]$ git config --global color.ui true

[jerry@CentOS project]$ git config --global color.status auto

[jerry@CentOS project]$ git config --global color.branch auto

Установка редактора по умолчанию

По умолчанию Git использует системный редактор по умолчанию, который берется из переменной среды VISUAL или EDITOR. Мы можем настроить другой, используя git config.

[jerry@CentOS project]$ git config --global core.editor vim

Установка инструмента merge по умолчанию

Git не предоставляет инструмент merge по умолчанию для интеграции конфликтующих изменений в ваше рабочее древо. Мы можем установить инструмент merge по умолчанию, включив следующие настройки.

[jerry@CentOS project]$ git config --global merge.tool vimdiff

Вывод настроек Git

Чтобы проверить настройки Git в локальном репозитории, используйте команду git config –list, как показано ниже.

[jerry@CentOS ~]$ git config --list

Приведенная выше команда даст следующий результат.

user.name=Jerry Mouse
user.email=jerry@tutorialspoint.com
push.default=nothing
branch.autosetuprebase=always
color.ui=true
color.status=auto
color.branch=auto
core.editor=vim
merge.tool=vimdiff

Жизненный цикл

В этой главе мы обсудим жизненный цикл Git. В следующих главах мы рассмотрим команды Git для каждой операции.

Общий рабочий процесс выглядит следующим образом –

  • Вы клонируете репозиторий Git как рабочую копию.
  • Вы изменяете рабочую копию, добавляя / редактируя файлы.
  • При необходимости вы также обновляете рабочую копию, принимая изменения других разработчиков.
  • Вы просматриваете изменения перед фиксацией.
  • Вы фиксируете изменения. Если все в порядке, то вы отправляете изменения в репозиторий.
  • После фиксации, если вы понимаете, что что-то не так, вы исправляете последнюю фиксацию и отправляете изменения в репозиторий.

Ниже показано графическое изображение рабочего процесса.

Git Tutorial

Операция Create

В этой главе мы увидим, как создать удаленный репозиторий Git; с этого момента мы будем называть его Git Server. Нам нужен сервер Git для совместной работы команды.

Создать нового пользователя

# add new group
[root@CentOS ~]# groupadd dev

# add new user
[root@CentOS ~]# useradd -G devs -d /home/gituser -m -s /bin/bash gituser

# change password
[root@CentOS ~]# passwd gituser

Приведенная выше команда даст следующий результат.

Changing password for user gituser.
New password:
Retype new password:
passwd: all authentication token updated successfully.

Создать пустой репозиторий

Давайте инициализируем новый репозиторий с помощью команды init, за которой следует параметр –bare. Он инициализирует репозиторий без рабочего каталога. По соглашению, чистый репозиторий должен называться .git .

[gituser@CentOS ~]$ pwd
/home/gituser

[gituser@CentOS ~]$ mkdir project.git

[gituser@CentOS ~]$ cd project.git/

[gituser@CentOS project.git]$ ls

[gituser@CentOS project.git]$ git --bare init
Initialized empty Git repository in /home/gituser-m/project.git/

[gituser@CentOS project.git]$ ls
branches config description HEAD hooks info objects refs

Создание пары ключей RSA Public / Private RSA

Давайте рассмотрим процесс настройки Git-сервера, утилита ssh-keygen генерирует пару публичных / частных ключей RSA, которые мы будем использовать для аутентификации пользователя.

Откройте терминал и введите следующую команду и просто нажимайте ввод для каждого ввода. После успешного завершения он создаст каталог .ssh внутри домашнего каталога.

tom@CentOS ~]$ pwd
/home/tom

[tom@CentOS ~]$ ssh-keygen

Приведенная выше команда даст следующий результат.

Generating public/private rsa key pair.
Enter file in which to save the key (/home/tom/.ssh/id_rsa): Press Enter Only
Created directory '/home/tom/.ssh'.
Enter passphrase (empty for no passphrase): ---------------> Press Enter Only
Enter same passphrase again: ------------------------------> Press Enter Only
Your identification has been saved in /home/tom/.ssh/id_rsa.
Your public key has been saved in /home/tom/.ssh/id_rsa.pub.
The key fingerprint is:
df:93:8c:a1:b8:b7:67:69:3a:1f:65:e8:0e:e9:25:a1 tom@CentOS
The key's randomart image is:
+--[ RSA 2048]----+
| |
| |
| |
|
.
|
| Soo |
| o*B. |
| E = *.= |
| oo==. . |
| ..+Oo
|
+-----------------+

ssh-keygen сгенерировал два ключа, первый из которых является частным (т.е. id_rsa), а второй – открытым (т.е. id_rsa.pub).

Примечание. Никогда не сообщайте свой ЧАСТНЫЙ КЛЮЧ другим людям.

Добавление ключей в authorized_keys

Предположим, что над проектом работают два разработчика, а именно Том и Джерри. Оба пользователя сгенерировали открытые ключи. Давайте посмотрим, как использовать эти ключи для аутентификации.

Том добавил свой открытый ключ на сервер с помощью команды ssh-copy-id, как показано ниже –

[tom@CentOS ~]$ pwd
/home/tom

[tom@CentOS ~]$ ssh-copy-id -i ~/.ssh/id_rsa.pub gituser@git.server.com

Приведенная выше команда даст следующий результат.

gituser@git.server.com's password:
Now try logging into the machine, with "ssh 'gituser@git.server.com'", and check in:
.ssh/authorized_keys
to make sure we haven't added extra keys that you weren't expecting.

Точно так же Джерри добавил свой открытый ключ на сервер с помощью команды ssh-copy-id.

[jerry@CentOS ~]$ pwd
/home/jerry

[jerry@CentOS ~]$ ssh-copy-id -i ~/.ssh/id_rsa gituser@git.server.com

Приведенная выше команда даст следующий результат.

gituser@git.server.com's password:
Now try logging into the machine, with "ssh 'gituser@git.server.com'", and check in:
.ssh/authorized_keys
to make sure we haven't added extra keys that you weren't expecting.

Отправление изменений в репозиторий

Мы создали чистый репозиторий на сервере и разрешили доступ двум пользователям. С этого момента Том и Джерри могут отправлять свои изменения в репозиторий, добавляя его как дистанционный.

Команда Git init создает каталог .git для хранения метаданных о репозитории каждый раз, когда считывает конфигурацию из файла .git/config.

Том создает новый каталог, добавляет файл README и фиксирует свое изменение как начальную фиксацию. После фиксации он проверяет сообщение фиксации, выполнив команду git log.

[tom@CentOS ~]$ pwd
/home/tom

[tom@CentOS ~]$ mkdir tom_repo

[tom@CentOS ~]$ cd tom_repo/

[tom@CentOS tom_repo]$ git init
Initialized empty Git repository in /home/tom/tom_repo/.git/

[tom@CentOS tom_repo]$ echo 'TODO: Add contents for README' > README

[tom@CentOS tom_repo]$ git status -s
?? README

[tom@CentOS tom_repo]$ git add .

[tom@CentOS tom_repo]$ git status -s
A README

[tom@CentOS tom_repo]$ git commit -m 'Initial commit'

Приведенная выше команда даст следующий результат.

[master (root-commit) 19ae206] Initial commit
1 files changed, 1 insertions(+), 0 deletions(-)
create mode 100644 README

Том проверяет сообщение журнала, выполнив команду git log.

[tom@CentOS tom_repo]$ git log

Приведенная выше команда даст следующий результат.

commit 19ae20683fc460db7d127cf201a1429523b0e319
Author: Tom Cat <tom@tutorialspoint.com>
Date: Wed Sep 11 07:32:56 2013 +0530

Initial commit

Том зафиксировал свои изменения в локальном репозитории. Теперь пришло время отправить изменения в удаленный репозиторий. Но перед этим надо добавить репозиторий как пульт, это разовая операция. После этого он может безопасно отправить изменения в удаленный репозиторий.

Примечание. По умолчанию Git отправляет только соответствующие ветки: для каждой ветки, которая существует на локальной стороне, удаленная сторона обновляется, если ветка с таким же именем уже существует там. В наших руководствах каждый раз, когда мы отправляем изменения в исходную главную ветку, используйте соответствующее имя ветки в соответствии с вашими требованиями.

[tom@CentOS tom_repo]$ git remote add origin gituser@git.server.com:project.git

[tom@CentOS tom_repo]$ git push origin master

Приведенная выше команда даст следующий результат.

Counting objects: 3, done.
Writing objects: 100% (3/3), 242 bytes, done.
Total 3 (delta 0), reused 0 (delta 0)
To gituser@git.server.com:project.git
* [new branch]
master −> master

Теперь изменения успешно зафиксированы в удаленном репозитории.

Операция Clone

У нас есть пустой репозиторий на сервере Git, и Том также выпустил свою первую версию. Теперь Джерри может просматривать свои изменения. Операция Clone создает экземпляр удаленного репозитория.

Джерри создает новый каталог в своем домашнем каталоге и выполняет операцию клонирования.

[jerry@CentOS ~]$ mkdir jerry_repo

[jerry@CentOS ~]$ cd jerry_repo/

[jerry@CentOS jerry_repo]$ git clone gituser@git.server.com:project.git

Приведенная выше команда даст следующий результат.

Initialized empty Git repository in /home/jerry/jerry_repo/project/.git/
remote: Counting objects: 3, done.
Receiving objects: 100% (3/3), 241 bytes, done.
remote: Total 3 (delta 0), reused 0 (delta 0)

Джерри меняет каталог на новый локальный репозиторий и перечисляет его содержимое.

[jerry@CentOS jerry_repo]$ cd project/

[jerry@CentOS jerry_repo]$ ls
README

Perform изменения

Джерри клонирует репозиторий и решает реализовать основные строковые операции. Итак, он создает файл string.c. После добавления содержимого string.c будет выглядеть следующим образом:

#include <stdio.h>

int my_strlen(char *s)
{
   char *p = s;

   while (*p)
      ++p;

   return (p - s);
}

int main(void)
{
   int i;
   char *s[] = 
   {
      "Git tutorials",
      "Tutorials Point"
   };

   for (i = 0; i < 2; ++i)
      
   printf("string lenght of %s = %d\n", s[i], my_strlen(s[i]));

   return 0;
}

Он скомпилировал и протестировал свой код, и все работает нормально. Теперь он может безопасно добавить эти изменения в репозиторий.

Операция Git add добавляет файл в область подготовки.

[jerry@CentOS project]$ git status -s
?? string
?? string.c

[jerry@CentOS project]$ git add string.c

Git показывает вопросительный знак перед именами файлов. Очевидно, что эти файлы не являются частью Git, и именно поэтому Git не знает, что с этими файлами делать. Вот почему Git показывает вопросительный знак перед именами файлов.

Джерри добавил файл в область хранения, команда git status покажет файлы, присутствующие в области подготовки.

[jerry@CentOS project]$ git status -s
A string.c
?? string

Чтобы зафиксировать изменения, он использовал команду git commit с опцией –m. Если мы опускаем опцию –m. Git откроет текстовый редактор, в котором мы можем написать многострочное сообщение commit.

[jerry@CentOS project]$ git commit -m 'Implemented my_strlen function'

Приведенная выше команда даст следующий результат –

[master cbe1249] Implemented my_strlen function
1 files changed, 24 insertions(+), 0 deletions(-)
create mode 100644 string.c

После commit для просмотра сведений журнала он запускает команду git log. Он будет отображать информацию обо всех коммитах с их commit ID, commit author, commit date и хешем SHA-1 фиксации.

[jerry@CentOS project]$ git log

Приведенная выше команда даст следующий результат –

commit cbe1249b140dad24b2c35b15cc7e26a6f02d2277
Author: Jerry Mouse <jerry@tutorialspoint.com>
Date: Wed Sep 11 08:05:26 2013 +0530

Implemented my_strlen function


commit 19ae20683fc460db7d127cf201a1429523b0e319
Author: Tom Cat <tom@tutorialspoint.com>
Date: Wed Sep 11 07:32:56 2013 +0530

Initial commit

Review изменения

После просмотра деталей фиксации Джерри понимает, что длина строки не может быть отрицательной, поэтому он решает изменить тип возвращаемого значения функции my_strlen.

Джерри использует команду git log для просмотра деталей журнала.

[jerry@CentOS project]$ git log

Приведенная выше команда даст следующий результат.

commit cbe1249b140dad24b2c35b15cc7e26a6f02d2277
Author: Jerry Mouse <jerry@tutorialspoint.com>
Date: Wed Sep 11 08:05:26 2013 +0530

Implemented my_strlen function

Джерри использует команду git show для просмотра деталей коммита. Команда git show принимает в качестве параметра идентификатор фиксации SHA-1.

[jerry@CentOS project]$ git show cbe1249b140dad24b2c35b15cc7e26a6f02d2277

Приведенная выше команда даст следующий результат –

commit cbe1249b140dad24b2c35b15cc7e26a6f02d2277
Author: Jerry Mouse <jerry@tutorialspoint.com>
Date: Wed Sep 11 08:05:26 2013 +0530

Implemented my_strlen function


diff --git a/string.c b/string.c
new file mode 100644
index 0000000..187afb9
--- /dev/null
+++ b/string.c
@@ -0,0 +1,24 @@
+#include <stdio.h>
+
+int my_strlen(char *s)
+{
   +
   char *p = s;
   +
   +
   while (*p)
   + ++p;
   + return (p -s );
   +
}
+

Он меняет тип возвращаемого значения функции с int на size_t. После тестирования кода он проверяет свои изменения, выполнив команду git diff.

[jerry@CentOS project]$ git diff

Приведенная выше команда даст следующий результат –

diff --git a/string.c b/string.c
index 187afb9..7da2992 100644
--- a/string.c
+++ b/string.c
@@ -1,6 +1,6 @@
#include <stdio.h>

-int my_strlen(char *s)
+size_t my_strlen(char *s)
{
   char *p = s;
   @@ -18,7 +18,7 @@ int main(void)
};
for (i = 0; i < 2; ++i)
{
   - printf("string lenght of %s = %d\n", s[i], my_strlen(s[i]));
   + printf("string lenght of %s = %lu\n", s[i], my_strlen(s[i]));
   return 0;
}

Git diff показывает знак «+» перед новыми добавленными строками и «-» для удаленных строк.

Commit изменения

Джерри уже зафиксировал изменения и хочет исправить свой последний коммит. В этом случае поможет операция git 180. Операция изменения изменяет последний коммит, включая ваше сообщение коммита; он создает новый идентификатор коммита.

Перед операцией изменения он проверяет журнал коммита.

[jerry@CentOS project]$ git log

Приведенная выше команда даст следующий результат.

commit cbe1249b140dad24b2c35b15cc7e26a6f02d2277
Author: Jerry Mouse <jerry@tutorialspoint.com>
Date: Wed Sep 11 08:05:26 2013 +0530

Implemented my_strlen function


commit 19ae20683fc460db7d127cf201a1429523b0e319
Author: Tom Cat <tom@tutorialspoint.com>
Date: Wed Sep 11 07:32:56 2013 +0530

Initial commit

Джерри фиксирует новые изменения с помощью операции -- amend и просматривает журнал коммита.

[jerry@CentOS project]$ git status -s
M string.c
?? string

[jerry@CentOS project]$ git add string.c

[jerry@CentOS project]$ git status -s
M string.c
?? string

[jerry@CentOS project]$ git commit --amend -m 'Changed return type of my_strlen to size_t'
[master d1e19d3] Changed return type of my_strlen to size_t
1 files changed, 24 insertions(+), 0 deletions(-)
create mode 100644 string.c

Теперь git log покажет новое сообщение коммита с новым идентификатором commit ID –

[jerry@CentOS project]$ git log

Приведенная выше команда даст следующий результат.

commit d1e19d316224cddc437e3ed34ec3c931ad803958
Author: Jerry Mouse <jerry@tutorialspoint.com>
Date: Wed Sep 11 08:05:26 2013 +0530

Changed return type of my_strlen to size_t


commit 19ae20683fc460db7d127cf201a1429523b0e319
Author: Tom Cat <tom@tutorialspoint.com>
Date: Wed Sep 11 07:32:56 2013 +0530

Initial commit

Push операция

Джерри изменил свой последний коммит, используя операцию amend, и он готов отправить(push) изменения. Операция Push сохраняет данные постоянно в репозитории Git. После успешной операции отправки другие разработчики смогут увидеть изменения Джерри.

Он выполняет команду git log, чтобы просмотреть детали коммита.

[jerry@CentOS project]$ git log

Приведенная выше команда даст следующий результат:

commit d1e19d316224cddc437e3ed34ec3c931ad803958
Author: Jerry Mouse <jerry@tutorialspoint.com>
Date: Wed Sep 11 08:05:26 2013 +0530

Changed return type of my_strlen to size_t

Перед операцией push он хочет просмотреть свои изменения, поэтому он использует команду git show для просмотра своих изменений.

[jerry@CentOS project]$ git show d1e19d316224cddc437e3ed34ec3c931ad803958

Приведенная выше команда даст следующий результат:

commit d1e19d316224cddc437e3ed34ec3c931ad803958
Author: Jerry Mouse <jerry@tutorialspoint.com>
Date: Wed Sep 11 08:05:26 2013 +0530

Changed return type of my_strlen to size_t

diff --git a/string.c b/string.c
new file mode 100644
index 0000000..7da2992
--- /dev/null
+++ b/string.c
@@ -0,0 +1,24 @@
+#include <stdio.h>
+
+size_t my_strlen(char *s)
+
{
   +
   char *p = s;
   +
   +
   while (*p)
   + ++p;
   + return (p -s );
   +
}
+
+int main(void)
+
{
   + int i;
   + char *s[] = 
   {
      + "Git tutorials",
      + "Tutorials Point"
      +
   };
   +
   +
   +
   for (i = 0; i < 2; ++i)
   printf("string lenght of %s = %lu\n", s[i], my_strlen(s[i]));
   +
   +
   return 0;
   +
}

Джерри доволен своими изменениями, и он готов отправить свои изменения.

[jerry@CentOS project]$ git push origin master

Приведенная выше команда даст следующий результат:

Counting objects: 4, done.
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 517 bytes, done.
Total 3 (delta 0), reused 0 (delta 0)
To gituser@git.server.com:project.git
19ae206..d1e19d3 master −> master

Изменения Джерри были успешно отправлены в репозиторий; теперь другие разработчики могут просматривать его изменения, выполняя операцию клонирования или обновления.

Update операция

Изменение существующущей функции

Том выполняет операцию клонирования и находит новый файл string.c. Он хочет знать, кто добавил этот файл в репозиторий и с какой целью, поэтому он выполняет команду git log.

[tom@CentOS ~]$ git clone gituser@git.server.com:project.git

Приведенная выше команда даст следующий результат –

Initialized empty Git repository in /home/tom/project/.git/
remote: Counting objects: 6, done.
remote: Compressing objects: 100% (4/4), done.
Receiving objects: 100% (6/6), 726 bytes, done.
remote: Total 6 (delta 0), reused 0 (delta 0)

Операция Clone создаст новый каталог внутри текущего рабочего каталога. Он меняет каталог на вновь созданный каталог и выполняет команду git log.

[tom@CentOS ~]$ cd project/

[tom@CentOS project]$ git log

Приведенная выше команда даст следующий результат –

commit d1e19d316224cddc437e3ed34ec3c931ad803958
Author: Jerry Mouse <jerry@tutorialspoint.com>
Date: Wed Sep 11 08:05:26 2013 +0530

Changed return type of my_strlen to size_t


commit 19ae20683fc460db7d127cf201a1429523b0e319
Author: Tom Cat <tom@tutorialspoint.com>
Date: Wed Sep 11 07:32:56 2013 +0530

Initial commit

После просмотра журнала он понимает, что файл string.c был добавлен Джерри для реализации основных строковых операций. Ему интересно узнать код Джерри. Итак, он открывает string.c в текстовом редакторе и сразу находит ошибку. В функции my_strlen Джерри не использует постоянный указатель. Итак, он решает изменить код Джерри. После модификации код выглядит следующим образом –

[tom@CentOS project]$ git diff

Приведенная выше команда даст следующий результат –

diff --git a/string.c b/string.c
index 7da2992..32489eb 100644
--- a/string.c
+++ b/string.c
@@ -1,8 +1,8 @@
#include <stdio.h>
-size_t my_strlen(char *s)
+size_t my_strlen(const char *s)
{
   - char *p = s;
   + const char *p = s;
   while (*p)
   ++p;
}

После тестирования он делает коммит своего изменения.

[tom@CentOS project]$ git status -s
M string.c
?? string

[tom@CentOS project]$ git add string.c

[tom@CentOS project]$ git commit -m 'Changed char pointer to const char pointer'
[master cea2c00] Changed char pointer to const char pointer
1 files changed, 2 insertions(+), 2 deletions(-)

[tom@CentOS project]$ git log

Приведенная выше команда даст следующий результат –

commit cea2c000f53ba99508c5959e3e12fff493b
Author: Tom Cat <tom@tutorialspoint.com>
Date: Wed Sep 11 08:32:07 2013 +0530

Changed char pointer to const char pointer


commit d1e19d316224cddc437e3ed34ec3c931ad803958
Author: Jerry Mouse <jerry@tutorialspoint.com>
Date: Wed Sep 11 08:05:26 2013 +0530

Changed return type of my_strlen to size_t


commit 19ae20683fc460db7d127cf201a1429523b0e319
Author: Tom Cat <tom@tutorialspoint.com>
Date: Wed Sep 11 07:32:56 2013 +0530
Initial commit

Том использует команду git push, чтобы отправить свои изменения.

[tom@CentOS project]$ git push origin master

Приведенная выше команда даст следующий результат –

Counting objects: 5, done.
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 336 bytes, done.
Total 3 (delta 1), reused 0 (delta 0)
To gituser@git.server.com:project.git
d1e19d3..cea2c00 master −> master

Добавить новую функцию

Тем временем Джерри решает реализовать функцию сравнения строк. Итак, он модифицирует string.c. После модификации файл выглядит следующим образом –

[jerry@CentOS project]$ git diff

Приведенная выше команда даст следующий результат –

index 7da2992..bc864ed 100644
--- a/string.c
+++ b/string.c
30Git Tutorials
@@ -9,9 +9,20 @@ size_t my_strlen(char *s)
return (p -s );
}
+char *my_strcpy(char *t, char *s)
+
{
   +
   char *p = t;
   +
   + while (*t++ = *s++)
   + ;
   +
   +
   return p;
   +
}
+
int main(void)
{
   int i; 
   +
   char p1[32];
   char *s[] = 
   {
      "Git tutorials",
      "Tutorials Point"
      @@ -20,5 +31,7 @@ int main(void)
      for (i = 0; i < 2; ++i)
      printf("string lenght of %s = %lu\n", s[i], my_strlen(s[i]));
      +
      printf("%s\n", my_strcpy(p1, "Hello, World !!!"));
      +
      return 0;
   }
}

После тестирования он готов внести свои изменения.

[jerry@CentOS project]$ git status -s
M string.c
?? string

[jerry@CentOS project]$ git add string.c

[jerry@CentOS project]$ git commit -m "Added my_strcpy function"
[master e944e5a] Added my_strcpy function
1 files changed, 13 insertions(+), 0 deletions(-)

Перед операцией push он проверяет фиксацию, просматривая сообщения журнала.

[jerry@CentOS project]$ git log

Приведенная выше команда даст следующий результат –

commit e944e5aab74b26e7447d3281b225309e4e59efcd
Author: Jerry Mouse <jerry@tutorialspoint.com>
Date: Wed Sep 11 08:41:42 2013 +0530

Added my_strcpy function


commit d1e19d316224cddc437e3ed34ec3c931ad803958
Author: Jerry Mouse <jerry@tutorialspoint.com>
Date: Wed Sep 11 08:05:26 2013 +0530

Changed return type of my_strlen to size_t


commit 19ae20683fc460db7d127cf201a1429523b0e319
Author: Tom Cat <tom@tutorialspoint.com>
Date: Wed Sep 11 07:32:56 2013 +0530

Initial commit

Джерри доволен изменениями, и он хочет их отправить.

[jerry@CentOS project]$ git push origin master

Приведенная выше команда даст следующий результат –

To gituser@git.server.com:project.git
! [rejected]
master −> master (non-fast-forward)
error: failed to push some refs to 'gituser@git.server.com:project.git'
To prevent you from losing history, non-fast-forward updates were rejected
Merge the remote changes before pushing again. See the 'Note about
fast-forwards' section of 'git push --help' for details.

Но Git не позволяет Джерри отправить свои изменения. Потому что Git определил, что удаленный репозиторий и локальный репозиторий Джерри не синхронизированы. Из-за этого он может потерять историю проекта. Чтобы избежать этого беспорядка, Git провалил эту операцию. Теперь Джерри должен сначала обновить локальный репозиторий, и только после этого он сможет внести свои изменения.

Получить последние изменения

Джерри выполняет команду git pull для синхронизации своего локального репозитория с удаленным.

[jerry@CentOS project]$ git pull

Приведенная выше команда даст следующий результат –

remote: Counting objects: 5, done.
remote: Compressing objects: 100% (3/3), done.
remote: Total 3 (delta 1), reused 0 (delta 0)
Unpacking objects: 100% (3/3), done.
From git.server.com:project
d1e19d3..cea2c00 master −> origin/master
First, rewinding head to replay your work on top of it...
Applying: Added my_strcpy function

После операции pull, Джерри проверяет сообщения журнала и находит сведения о commit Тома с commit ID cea2c000f53ba99508c5959e3e12fff493ba6f69.

[jerry@CentOS project]$ git log

Приведенная выше команда даст следующий результат –

commit e86f0621c2a3f68190bba633a9fe6c57c94f8e4f
Author: Jerry Mouse <jerry@tutorialspoint.com>
Date: Wed Sep 11 08:41:42 2013 +0530

Added my_strcpy function


commit cea2c000f53ba99508c5959e3e12fff493ba6f69
Author: Tom Cat <tom@tutorialspoint.com>
Date: Wed Sep 11 08:32:07 2013 +0530

Changed char pointer to const char pointer


commit d1e19d316224cddc437e3ed34ec3c931ad803958
Author: Jerry Mouse <jerry@tutorialspoint.com>
Date: Wed Sep 11 08:05:26 2013 +0530

Changed return type of my_strlen to size_t


commit 19ae20683fc460db7d127cf201a1429523b0e319
Author: Tom Cat <tom@tutorialspoint.com>
Date: Wed Sep 11 07:32:56 2013 +0530
Initial commit

Теперь локальный репозиторий Джерри полностью синхронизирован с удаленным репозиторием. Так что он может спокойно отправлять свои изменения.

[jerry@CentOS project]$ git push origin master

Приведенная выше команда даст следующий результат –

Counting objects: 5, done.
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 455 bytes, done.
Total 3 (delta 1), reused 0 (delta 0)
To gituser@git.server.com:project.git
cea2c00..e86f062 master −&gt; master

Stash операция

Предположим, вы внедряете новую функцию для своего продукта. Ваш код находится в разработке, и внезапно приходит эскалация клиентов. Из-за этого вам придется отложить работу над новой функцией на несколько часов. Вы не можете сделать коммит своего частичного кода, а также не можете выбросить свои изменения. Поэтому вам нужно временное пространство, где вы можете сохранить свои частичные изменения, а затем сделать их коммит.

В Git операция stash берет ваши измененные отслеживаемые файлы, обрабатывает изменения и сохраняет их в стеке незавершенных изменений, которые вы можете повторно применить в любое время.

[jerry@CentOS project]$ git status -s
M string.c
?? string

Теперь вы хотите сменить ветвь для эскалации клиентов, но не хотите делать коммит того, над чем еще работали; так что вы сохраните изменения. Чтобы отправить новый stash в свой стек, выполните команду git stash.

[jerry@CentOS project]$ git stash
Saved working directory and index state WIP on master: e86f062 Added my_strcpy function
HEAD is now at e86f062 Added my_strcpy function

Теперь ваш рабочий каталог чист, и все изменения сохранены в стеке. Давайте проверим это с помощью команды git status.

[jerry@CentOS project]$ git status -s
?? string

Теперь вы можете смело переключать ветку и работать в другом месте. Мы можем просмотреть список сохраненных изменений, используя команду git stash list.

[jerry@CentOS project]$ git stash list
stash@{0}: WIP on master: e86f062 Added my_strcpy function

Предположим, вы разрешили проблему эскалации клиентов и вернулись к своей новой функции в поисках своего недоделанного кода, просто выполните команду git stash pop, чтобы удалить изменения из стека и поместить их в текущий рабочий каталог.

[jerry@CentOS project]$ git status -s
?? string

[jerry@CentOS project]$ git stash pop

Приведенная выше команда даст следующий результат:

# On branch master
# Changed but not updated:
# (use "git add ..." to update what will be committed)
# (use "git checkout -- ..." to discard changes in working directory)
#
#
modified: string.c
#
# Untracked files:
# (use "git add ..." to include in what will be committed)
#
#
string
no changes added to commit (use "git add" and/or "git commit -a")
Dropped refs/stash@{0} (36f79dfedae4ac20e2e8558830154bd6315e72d4)

[jerry@CentOS project]$ git status -s
M string.c
?? string

Move операция

Как следует из названия, операция move перемещает каталог или файл из одного места в другое. Том решает переместить исходный код в каталог src. Измененная структура каталогов будет выглядеть следующим образом –

[tom@CentOS project]$ pwd
/home/tom/project

[tom@CentOS project]$ ls
README string string.c

[tom@CentOS project]$ mkdir src

[tom@CentOS project]$ git mv string.c src/

[tom@CentOS project]$ git status -s
R string.c −> src/string.c
?? string

Чтобы сделать эти изменения постоянными, мы должны отправить измененную структуру каталогов в удаленный репозиторий, чтобы другие разработчики могли это увидеть.

[tom@CentOS project]$ git commit -m "Modified directory structure"

[master 7d9ea97] Modified directory structure
1 files changed, 0 insertions(+), 0 deletions(-)
rename string.c => src/string.c (100%)

[tom@CentOS project]$ git push origin master
Counting objects: 4, done.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 320 bytes, done.
Total 3 (delta 0), reused 0 (delta 0)
To gituser@git.server.com:project.git
e86f062..7d9ea97 master −> master

В локальном репозитории Джерри перед операцией pull будет показана старая структура каталогов.

[jerry@CentOS project]$ pwd
/home/jerry/jerry_repo/project

[jerry@CentOS project]$ ls
README string string.c

Но после операции извлечения структура каталогов обновится. Теперь Джерри может видеть каталог src и файл, находящийся внутри этого каталога.

[jerry@CentOS project]$ git pull
remote: Counting objects: 4, done.
remote: Compressing objects: 100% (2/2), done.
remote: Total 3 (delta 0), reused 0 (delta 0)
Unpacking objects: 100% (3/3), done.
From git.server.com:project
e86f062..7d9ea97 master −> origin/master
First, rewinding head to replay your work on top of it...
Fast-forwarded master to 7d9ea97683da90bcdb87c28ec9b4f64160673c8a.

[jerry@CentOS project]$ ls
README src string

[jerry@CentOS project]$ ls src/
string.c

Rename операция

До сих пор и Том, и Джерри использовали ручные команды для компиляции своего проекта. Теперь Джерри решает создать Makefile для своего проекта, а также присвоить файлу собственное имя «string.c».

[jerry@CentOS project]$ pwd
/home/jerry/jerry_repo/project

[jerry@CentOS project]$ ls
README src

[jerry@CentOS project]$ cd src/

[jerry@CentOS src]$ git add Makefile

[jerry@CentOS src]$ git mv string.c string_operations.c

[jerry@CentOS src]$ git status -s
A Makefile
R string.c −> string_operations.c

Git показывает R перед именем файла, чтобы указать, что файл был переименован.

Для операции commit, Джерри использовал флаг -a, который заставляет git commit автоматически обнаруживать измененные файлы.

[jerry@CentOS src]$ git commit -a -m 'Added Makefile and renamed strings.c to
string_operations.c '

[master 94f7b26] Added Makefile and renamed strings.c to string_operations.c
1 files changed, 0 insertions(+), 0 deletions(-)
create mode 100644 src/Makefile
rename src/{string.c => string_operations.c} (100%)

После коммита он отправляет свои изменения в репозиторий.

[jerry@CentOS src]$ git push origin master

Приведенная выше команда даст следующий результат –

Counting objects: 6, done.
Compressing objects: 100% (3/3), done.
Writing objects: 100% (4/4), 396 bytes, done.
Total 4 (delta 0), reused 0 (delta 0)
To gituser@git.server.com:project.git
7d9ea97..94f7b26 master −> master

Теперь другие разработчики могут просматривать эти изменения, обновляя свой локальный репозиторий.

Delete операция

Том обновляет свой локальный репозиторий и находит скомпилированный двоичный файл в каталоге src. После просмотра сообщения о фиксации он понимает, что скомпилированный двоичный файл был добавлен Джерри.

[tom@CentOS src]$ pwd
/home/tom/project/src

[tom@CentOS src]$ ls
Makefile string_operations string_operations.c

[tom@CentOS src]$ file string_operations
string_operations: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses
shared libs), for GNU/Linux 2.6.18, not stripped

[tom@CentOS src]$ git log
commit 29af9d45947dc044e33d69b9141d8d2dad37cc62
Author: Jerry Mouse <jerry@tutorialspoint.com>
Date: Wed Sep 11 10:16:25 2013 +0530

Added compiled binary

VCS используется для хранения только исходного кода, а не исполняемых двоичных файлов. Итак, Том решает удалить этот файл из репозитория. Для дальнейшей работы он использует команду git rm.

[tom@CentOS src]$ ls
Makefile string_operations string_operations.c

[tom@CentOS src]$ git rm string_operations
rm 'src/string_operations'

[tom@CentOS src]$ git commit -a -m "Removed executable binary"

[master 5776472] Removed executable binary
1 files changed, 0 insertions(+), 0 deletions(-)
delete mode 100755 src/string_operations

После коммита он отправляет свои изменения в репозиторий.

[tom@CentOS src]$ git push origin master

Приведенная выше команда даст следующий результат.

Counting objects: 5, done.
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 310 bytes, done.
Total 3 (delta 1), reused 0 (delta 0)
To gituser@git.server.com:project.git
29af9d4..5776472 master −> master

Исправление ошибок

Человеку свойственно ошибаться. Таким образом, каждая VCS предоставляет возможность исправлять ошибки до определенного момента. Git предоставляет функцию, которую мы можем использовать для отмены изменений, внесенных в локальный репозиторий.

Предположим, пользователь случайно внес некоторые изменения в свой локальный репозиторий, а затем хочет отменить эти изменения. В таких случаях важную роль играет операция возврата(revert).

Отмена незафиксированных изменений

Предположим, Джерри случайно изменяет файл из своего локального репозитория. Но он хочет отменить свою модификацию. Чтобы справиться с этой ситуацией, мы можем использовать команду git checkout. Мы можем использовать эту команду, чтобы вернуть содержимое файла.

[jerry@CentOS src]$ pwd
/home/jerry/jerry_repo/project/src

[jerry@CentOS src]$ git status -s
M string_operations.c

[jerry@CentOS src]$ git checkout string_operations.c

[jerry@CentOS src]$ git status –s

Кроме того, мы можем использовать команду git checkout для получения удаленного файла из локального репозитория. Предположим, Том удаляет файл из локального репозитория, и мы хотим вернуть этот файл. Мы можем добиться этого, используя ту же команду.

[tom@CentOS src]$ pwd
/home/tom/top_repo/project/src

[tom@CentOS src]$ ls -1
Makefile
string_operations.c

[tom@CentOS src]$ rm string_operations.c

[tom@CentOS src]$ ls -1
Makefile

[tom@CentOS src]$ git status -s
D string_operations.c

Git показывает букву D перед именем файла. Это означает, что файл был удален из локального репозитория.

[tom@CentOS src]$ git checkout string_operations.c

[tom@CentOS src]$ ls -1
Makefile
string_operations.c

[tom@CentOS src]$ git status -s

Примечание. Мы можем выполнить все эти операции до коммита.

Удаление изменений из промежуточной области

Мы видели, что когда мы выполняем операцию добавления, файлы перемещаются из локального репозитория в указанную область. Если пользователь случайно изменяет файл и добавляет его в промежуточную область, он может отменить свои изменения с помощью команды git checkout.

В Git есть один указатель HEAD, который всегда указывает на последний коммит. Если вы хотите отменить изменение в поэтапной области, вы можете использовать команду git checkout, но с командой checkout вы должны указать дополнительный параметр, то есть указатель HEAD. Дополнительный параметр указателя коммита указывает команде git checkout сбросить рабочее древо, а также удалить поэтапные изменения.

Предположим, Том изменяет файл из своего локального репозитория. Если мы просмотрим статус этого файла, он покажет, что файл был изменен, но не добавлен в область подготовки.

tom@CentOS src]$ pwd
/home/tom/top_repo/project/src
# Unmodified file

[tom@CentOS src]$ git status -s

# Modify file and view it’s status.
[tom@CentOS src]$ git status -s
M string_operations.c

[tom@CentOS src]$ git add string_operations.c

Статус Git показывает, что файл присутствует в промежуточной области, теперь верните его, используя команду git checkout, и просмотрите статус возвращенного файла.

[tom@CentOS src]$ git checkout HEAD -- string_operations.c

[tom@CentOS src]$ git status -s

Перемещение указателя HEAD с помощью Git Reset

Сделав несколько изменений, вы можете решить удалить эти изменения. Команда сброса Git используется для сброса или отмены изменений. Мы можем выполнить три различных типа операций сброса.

На диаграмме ниже показано графическое представление команды сброса Git.

git Tutorial
git Tutorial

Soft

Каждая ветка имеет указатель HEAD, указывающий на последнюю фиксацию. Если мы используем команду сброса Git с параметром –soft, за которым следует commit ID, тогда он сбросит только указатель HEAD, ничего не разрушая.

В файле .git/refs/Heads/ master хранится идентификатор фиксации указателя HEAD. Мы можем проверить это с помощью команды git log -1.

[jerry@CentOS project]$ cat .git/refs/heads/master
577647211ed44fe2ae479427a0668a4f12ed71a1

Теперь просмотрите последний commit ID, который будет соответствовать указанному выше commit ID.

[jerry@CentOS project]$ git log -2

Приведенная выше команда даст следующий результат.

commit 577647211ed44fe2ae479427a0668a4f12ed71a1
Author: Tom Cat <tom@tutorialspoint.com>
Date: Wed Sep 11 10:21:20 2013 +0530

Removed executable binary


commit 29af9d45947dc044e33d69b9141d8d2dad37cc62
Author: Jerry Mouse <jerry@tutorialspoint.com>
Date: Wed Sep 11 10:16:25 2013 +0530

Added compiled binary

Сбросим указатель HEAD.

[jerry@CentOS project]$ git reset --soft HEAD~

Теперь мы просто сбрасываем указатель HEAD назад на одну позицию. Проверим содержимое файла .git/refs/Head/master.

[jerry@CentOS project]$ cat .git/refs/heads/master
29af9d45947dc044e33d69b9141d8d2dad37cc62

Commit ID из файла изменен, теперь проверьте его, просмотрев сообщения коммита.

jerry@CentOS project]$ git log -2

Приведенная выше команда даст следующий результат.

commit 29af9d45947dc044e33d69b9141d8d2dad37cc62
Author: Jerry Mouse <jerry@tutorialspoint.com>
Date: Wed Sep 11 10:16:25 2013 +0530

Added compiled binary


commit 94f7b26005f856f1a1b733ad438e97a0cd509c1a
Author: Jerry Mouse <jerry@tutorialspoint.com>
Date: Wed Sep 11 10:08:01 2013 +0530

Added Makefile and renamed strings.c to string_operations.c

mixed

Git reset с параметром –mixed отменяет те изменения из промежуточной области, которые еще не были зафиксированы. Он отменяет изменения только из области подготовки. Фактические изменения, внесенные в рабочую копию файла, не затрагиваются. Сброс Git по умолчанию эквивалентен сбросу git – смешанному.

hard

Если вы используете опцию –hard с командой сброса Git, она очистит промежуточную область; он сбросит указатель HEAD на последний коммит конкретного идентификатора фиксации и также удалит изменения локального файла.

Давайте проверим commit ID.

[jerry@CentOS src]$ pwd
/home/jerry/jerry_repo/project/src

[jerry@CentOS src]$ git log -1

Приведенная выше команда даст следующий результат.

commit 577647211ed44fe2ae479427a0668a4f12ed71a1
Author: Tom Cat <tom@tutorialspoint.com>
Date: Wed Sep 11 10:21:20 2013 +0530

Removed executable binary

Джерри изменил файл, добавив однострочный комментарий в начале файла.

[jerry@CentOS src]$ head -2 string_operations.c
/* This line be removed by git reset operation */
#include <stdio.h>

Он проверил это с помощью команды git status.

[jerry@CentOS src]$ git add string_operations.c
[jerry@CentOS src]$ git status

Приведенная выше команда даст следующий результат.

# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
#
modified: string_operations.c
#

Статус Git показывает, что файл присутствует в промежуточной области. Теперь сбросьте HEAD с опцией – hard.

[jerry@CentOS src]$ git reset --hard 577647211ed44fe2ae479427a0668a4f12ed71a1

HEAD is now at 5776472 Removed executable binary

Команда сброса Git выполнена успешно, которая вернет файл из промежуточной области, а также удалит все локальные изменения, внесенные в файл.

[jerry@CentOS src]$ git status -s

Статус Git показывает, что файл был возвращен из промежуточной области.

[jerry@CentOS src]$ head -2 string_operations.c
#include <stdio.h>

Команда head также показывает, что операция сброса также удалила локальные изменения.

Tag операция

Операция Tag позволяет дать осмысленные имена конкретной версии в репозитории. Предположим, Том и Джерри решили пометить код своего проекта, чтобы впоследствии легко получить к нему доступ.

Создание тэгов

Давайте пометим текущий HEAD с помощью команды git tag. Том предоставляет имя тега с параметром -a и предоставляет сообщение тега с параметром –m.

tom@CentOS project]$ pwd
/home/tom/top_repo/project

[tom@CentOS project]$ git tag -a 'Release_1_0' -m 'Tagged basic string operation code' HEAD

Если вы хотите пометить конкретный коммит, используйте соответствующий идентификатор COMMIT вместо указателя HEAD. Том использует следующую команду, чтобы поместить тег в удаленный репозиторий.

[tom@CentOS project]$ git push origin tag Release_1_0

Приведенная выше команда даст следующий результат –

Counting objects: 1, done.
Writing objects: 100% (1/1), 183 bytes, done.
Total 1 (delta 0), reused 0 (delta 0)
To gituser@git.server.com:project.git
* [new tag]
Release_1_0 −> Release_1_0

Просмотр тегов

Том создал теги. Теперь Джерри может просматривать все доступные теги, используя команду Git tag с параметром –l.

[jerry@CentOS src]$ pwd
/home/jerry/jerry_repo/project/src

[jerry@CentOS src]$ git pull
remote: Counting objects: 1, done.
remote: Total 1 (delta 0), reused 0 (delta 0)
Unpacking objects: 100% (1/1), done.
From git.server.com:project
* [new tag]
Release_1_0 −> Release_1_0
Current branch master is up to date.

[jerry@CentOS src]$ git tag -l
Release_1_0

Джерри использует команду Git show, за которой следует имя тега, чтобы просмотреть дополнительные сведения о теге.

[jerry@CentOS src]$ git show Release_1_0

Приведенная выше команда даст следующий результат –

tag Release_1_0
Tagger: Tom Cat <tom@tutorialspoint.com>
Date: Wed Sep 11 13:45:54 2013 +0530

Tagged basic string operation code


commit 577647211ed44fe2ae479427a0668a4f12ed71a1
Author: Tom Cat <tom@tutorialspoint.com>
Date: Wed Sep 11 10:21:20 2013 +0530

Removed executable binary

diff --git a/src/string_operations b/src/string_operations
deleted file mode 100755
index 654004b..0000000
Binary files a/src/string_operations and /dev/null differ

Удаление тегов

Том использует следующую команду для удаления тегов как из локального, так и из удаленного репозитория.

[tom@CentOS project]$ git tag
Release_1_0

[tom@CentOS project]$ git tag -d Release_1_0
Deleted tag 'Release_1_0' (was 0f81ff4)
# Remove tag from remote repository.

[tom@CentOS project]$ git push origin :Release_1_0
To gituser@git.server.com:project.git
- [deleted]
Release_1_0

 Patch операция

Patch – это текстовый файл, содержимое которого похоже на Git diff, но вместе с кодом в нем также есть метаданные о коммитах; например, commit ID, дата, сообщение коммита и т. д. Мы можем создать патч из коммитов, и другие люди могут применить их к своему репозиторию.

Джерри реализует функцию strcat для своего проекта. Джерри может создать путь своего кода и отправить его Тому. Затем он может применить полученный патч к своему коду.

Джерри использует команду Git format-patch для создания патча для последней фиксации. Если вы хотите создать патч для конкретной фиксации, используйте COMMIT_ID с командой format-patch.

[jerry@CentOS project]$ pwd
/home/jerry/jerry_repo/project/src

[jerry@CentOS src]$ git status -s
M string_operations.c
?? string_operations

[jerry@CentOS src]$ git add string_operations.c

[jerry@CentOS src]$ git commit -m "Added my_strcat function"

[master b4c7f09] Added my_strcat function
1 files changed, 13 insertions(+), 0 deletions(-)

[jerry@CentOS src]$ git format-patch -1
0001-Added-my_strcat-function.patch

Вышеупомянутая команда создает файлы .patch внутри текущего рабочего каталога. Том может использовать этот патч для изменения своих файлов. Git предоставляет две команды для применения патчей git am и git apply соответственно. Git apply изменяет локальные файлы без создания коммита, тогда как git am изменяет файл и также создает коммит.

Чтобы применить патч и создать коммит, используйте следующую команду –

[tom@CentOS src]$ pwd
/home/tom/top_repo/project/src

[tom@CentOS src]$ git diff

[tom@CentOS src]$ git status –s

[tom@CentOS src]$ git apply 0001-Added-my_strcat-function.patch

[tom@CentOS src]$ git status -s
M string_operations.c
?? 0001-Added-my_strcat-function.patch

Патч успешно применен, теперь мы можем просмотреть изменения с помощью команды git diff.

[tom@CentOS src]$ git diff

Приведенная выше команда даст следующий результат –

diff --git a/src/string_operations.c b/src/string_operations.c
index 8ab7f42..f282fcf 100644
--- a/src/string_operations.c
+++ b/src/string_operations.c
@@ -1,5 +1,16 @@
#include <stdio.h>
+char *my_strcat(char *t, char *s)
diff --git a/src/string_operations.c b/src/string_operations.c
index 8ab7f42..f282fcf 100644
--- a/src/string_operations.c
+++ b/src/string_operations.c
@@ -1,5 +1,16 @@
#include <stdio.h>
+char *my_strcat(char *t, char *s)
+
{
   +
   char *p = t;
   +
   +
   +
   while (*p)
   ++p;
   +
   while (*p++ = *s++)
   + ;
   + return t;
   +
}
+
size_t my_strlen(const char *s)
{
   const char *p = s;
   @@ -23,6 +34,7 @@ int main(void)
   {

Управление ветвями

Операция Branch позволяет создать еще одно направление развития. Мы можем использовать эту операцию, чтобы разделить процесс разработки на два разных направления. Например, мы выпустили продукт для версии 6.0, и мы могли бы захотеть создать ветку, чтобы разработка функций 7.0 могла быть отделена от исправлений ошибок 6.0.

Создание ветки

Том создает новую ветку с помощью команды git branch <имя ветки>. Мы можем создать новую ветку из существующей. Мы можем использовать конкретный коммит или тег в качестве отправной точки. Если какой-либо конкретный commit ID не указан, тогда будет создана ветвь с HEAD в качестве отправной точки.

[jerry@CentOS src]$ git branch new_branch

[jerry@CentOS src]$ git branch
* master
new_branch

Создана новая ветка; Том использовал команду git branch, чтобы вывести список доступных веток. Git показывает звездочку перед выбранной веткой.

Наглядное представление операции создания ветки показано ниже –

git Tutorial
git Tutorial

Переключение между ветками

Джерри использует команду git checkout для переключения между ветвями.

[jerry@CentOS src]$ git checkout new_branch
Switched to branch 'new_branch'
[jerry@CentOS src]$ git branch
master
* new_branch

Ярлык для создания и переключения ветки

В приведенном выше примере мы использовали две команды для создания и переключения ветвей соответственно. Git предоставляет параметр –b с командой checkout; эта операция создает новую ветку и немедленно переключается на новую ветку.

[jerry@CentOS src]$ git checkout -b test_branch
Switched to a new branch 'test_branch'

[jerry@CentOS src]$ git branch
master
new_branch
* test_branch

Удаление ветки

Ветку можно удалить, указав параметр –D с командой git branch. Но перед удалением существующей ветки переключитесь на другую ветку.

Джерри в настоящее время находится на test_branch и хочет удалить эту ветку. Поэтому он переключает ветку и удаляет ветку, как показано ниже.

[jerry@CentOS src]$ git branch
master
new_branch
* test_branch

[jerry@CentOS src]$ git checkout master
Switched to branch 'master'

[jerry@CentOS src]$ git branch -D test_branch
Deleted branch test_branch (was 5776472).

Теперь Git покажет только две ветки.

[jerry@CentOS src]$ git branch
* master
new_branch

Переименовывание ветки

Джерри решает добавить поддержку широких символов в свой проект строковых операций. Он уже создал новую ветку, но имя ветки не подходит. Поэтому он меняет имя ветки, используя параметр –m, за которым следует имя старой ветки и имя новой ветки.

[jerry@CentOS src]$ git branch
* master
new_branch

[jerry@CentOS src]$ git branch -m new_branch wchar_support

Теперь команда git branch покажет новое имя ветки.

[jerry@CentOS src]$ git branch
* master
wchar_support

Объединие двух ветвей

Джерри реализует функцию для возврата длины строки из строки широких символов. Новый код будет выглядеть следующим образом –

[jerry@CentOS src]$ git branch
master
* wchar_support

[jerry@CentOS src]$ pwd
/home/jerry/jerry_repo/project/src

[jerry@CentOS src]$ git diff

Приведенная выше команда дает следующий результат –

t a/src/string_operations.c b/src/string_operations.c
index 8ab7f42..8fb4b00 100644
--- a/src/string_operations.c
+++ b/src/string_operations.c
@@ -1,4 +1,14 @@
#include <stdio.h>
+#include <wchar.h>
+
+size_t w_strlen(const wchar_t *s)
+
{
   +
   const wchar_t *p = s;
   +
   +
   while (*p)
   + ++p;
   + return (p - s);
   +
}

После тестирования он делает коммит и помещает свои изменения в новую ветку.

[jerry@CentOS src]$ git status -s
M string_operations.c
?? string_operations

[jerry@CentOS src]$ git add string_operations.c

[jerry@CentOS src]$ git commit -m 'Added w_strlen function to return string lenght of wchar_t
string'

[wchar_support 64192f9] Added w_strlen function to return string lenght of wchar_t string
1 files changed, 10 insertions(+), 0 deletions(-)

Обратите внимание, что Джерри переносит эти изменения в новую ветку, поэтому он использовал имя ветки wchar_support вместо главной ветки.

[jerry@CentOS src]$ git push origin wchar_support   <−−− Observer branch_name

Приведенная выше команда даст следующий результат.

Counting objects: 7, done.
Compressing objects: 100% (4/4), done.
Writing objects: 100% (4/4), 507 bytes, done.
Total 4 (delta 1), reused 0 (delta 0)
To gituser@git.server.com:project.git
* [new branch]
wchar_support -> wchar_support

После фиксации изменений новая ветка будет выглядеть следующим образом –

git Tutorial

Тому интересно, что делает Джерри в своей частной ветке, и он проверяет журнал ветки wchar_support.

[tom@CentOS src]$ pwd
/home/tom/top_repo/project/src

[tom@CentOS src]$ git log origin/wchar_support -2

Приведенная выше команда даст следующий результат.

commit 64192f91d7cc2bcdf3bf946dd33ece63b74184a3
Author: Jerry Mouse <jerry@tutorialspoint.com>
Date: Wed Sep 11 16:10:06 2013 +0530

Added w_strlen function to return string lenght of wchar_t string


commit 577647211ed44fe2ae479427a0668a4f12ed71a1
Author: Tom Cat <tom@tutorialspoint.com>
Date: Wed Sep 11 10:21:20 2013 +0530

Removed executable binary

Просматривая сообщения коммита, Том понимает, что Джерри реализовал функцию strlen для широких символов и ему нужна такая же функциональность в главной ветви. Вместо повторной реализации он решает взять код Джерри, объединив свою ветку с основной веткой.

[tom@CentOS project]$ git branch
* master

[tom@CentOS project]$ pwd
/home/tom/top_repo/project

[tom@CentOS project]$ git merge origin/wchar_support
Updating 5776472..64192f9
Fast-forward
src/string_operations.c | 10 ++++++++++
1 files changed, 10 insertions(+), 0 deletions(-)

После операции слияния главная ветвь будет выглядеть следующим образом:

git Tutorial

Теперь ветка wchar_support объединена с главной ветвью. Мы можем проверить это, просмотрев сообщение о фиксации или просмотрев изменения, внесенные в файл string_operation.c.

[tom@CentOS project]$ cd src/

[tom@CentOS src]$ git log -1

commit 64192f91d7cc2bcdf3bf946dd33ece63b74184a3
Author: Jerry Mouse 
Date: Wed Sep 11 16:10:06 2013 +0530

Added w_strlen function to return string lenght of wchar_t string

[tom@CentOS src]$ head -12 string_operations.c

Приведенная выше команда даст следующий результат.

#include <stdio.h>
#include <wchar.h>
size_t w_strlen(const wchar_t *s)
{
   const wchar_t *p = s;

   while (*p)
      ++p;

   return (p - s);
}

После тестирования он отправляет свои изменения кода в основную ветку.

[tom@CentOS src]$ git push origin master
Total 0 (delta 0), reused 0 (delta 0)
To gituser@git.server.com:project.git
5776472..64192f9 master −> master

Перебазировать ветви

Команда Git rebase – это команда слияния веток, но разница в том, что она изменяет порядок коммитов.

Команда Git merge пытается поместить коммиты из других веток поверх HEAD текущей локальной ветки. Например, ваша локальная ветка имеет коммиты A-> B-> C-> D, а ветвь слияния имеет коммиты A-> B-> X-> Y, тогда git merge преобразует текущую локальную ветвь во что-то вроде A-> B-> C-> D-> X-> Y

Команда Git rebase пытается найти общего предка между текущей локальной веткой и ветвью слияния. Затем он отправляет коммиты в локальную ветвь, изменяя порядок коммитов в текущей локальной ветке. Например, если ваша локальная ветка имеет коммиты A-> B-> C-> D, а ветвь слияния имеет коммиты A-> B-> X-> Y, то Git rebase преобразует текущую локальную ветку во что-то вроде A- > B-> X-> Y-> C-> D.

Когда несколько разработчиков работают с одним удаленным репозиторием, вы не можете изменить порядок коммитов в удаленном репозитории. В этой ситуации вы можете использовать операцию rebase, чтобы поместить ваши локальные коммиты поверх коммитов удаленного репозитория, и вы можете отправить эти изменения.

Разрешение конфликтов

Внесение изменений в ветку wchar_support

Джерри работает над веткой wchar_support. Он меняет название функций и после тестирования делает коммит своих изменений.

[jerry@CentOS src]$ git branch
 master
* wchar_support
[jerry@CentOS src]$ git diff

Приведенная выше команда дает следующий результат –

diff --git a/src/string_operations.c b/src/string_operations.c
index 8fb4b00..01ff4e0 100644
--- a/src/string_operations.c
+++ b/src/string_operations.c
@@ -1,7 +1,7 @@
#include <stdio.h>
#include <wchar.h>
-size_t w_strlen(const wchar_t *s)
+size_t my_wstrlen(const wchar_t *s)
{
   const wchar_t *p = s;

После проверки кода он фиксирует свои изменения.

[jerry@CentOS src]$ git status -s
M string_operations.c

[jerry@CentOS src]$ git add string_operations.c

[jerry@CentOS src]$ git commit -m 'Changed function name'
[wchar_support 3789fe8] Changed function name
1 files changed, 1 insertions(+), 1 deletions(-)

[jerry@CentOS src]$ git push origin wchar_support

Приведенная выше команда даст следующий результат –

Counting objects: 7, done.
Compressing objects: 100% (4/4), done.
Writing objects: 100% (4/4), 409 bytes, done.
Total 4 (delta 1), reused 0 (delta 0)
To gituser@git.server.com:project.git
64192f9..3789fe8 wchar_support -> wchar_support

Выполнение изменений в главной ветви

Тем временем в главной ветке Том также меняет имя той же функции и передает свои изменения в главную ветку.

[tom@CentOS src]$ git branch
* master
[tom@CentOS src]$ git diff

Приведенная выше команда дает следующий результат –

diff --git a/src/string_operations.c b/src/string_operations.c
index 8fb4b00..52bec84 100644
--- a/src/string_operations.c
+++ b/src/string_operations.c
@@ -1,7 +1,8 @@
#include <stdio.h>
#include <wchar.h>
-size_t w_strlen(const wchar_t *s)
+/* wide character strlen fucntion */
+size_t my_wc_strlen(const wchar_t *s)
{
   const wchar_t *p = s;

После проверки diff он фиксирует свои изменения.

[tom@CentOS src]$ git status -s
M string_operations.c

[tom@CentOS src]$ git add string_operations.c

[tom@CentOS src]$ git commit -m 'Changed function name from w_strlen to my_wc_strlen'
[master ad4b530] Changed function name from w_strlen to my_wc_strlen
1 files changed, 2 insertions(+), 1 deletions(-)

[tom@CentOS src]$ git push origin master

Приведенная выше команда даст следующий результат –

Counting objects: 7, done.
Compressing objects: 100% (4/4), done.
Writing objects: 100% (4/4), 470 bytes, done.
Total 4 (delta 1), reused 0 (delta 0)
To gituser@git.server.com:project.git
64192f9..ad4b530 master -> master

В ветви wchar_support Джерри реализует функцию strchr для строки широких символов. После тестирования он фиксирует и отправляет свои изменения в ветку wchar_support.

[jerry@CentOS src]$ git branch
master
* wchar_support
[jerry@CentOS src]$ git diff

Приведенная выше команда дает следующий результат –

diff --git a/src/string_operations.c b/src/string_operations.c
index 01ff4e0..163a779 100644
--- a/src/string_operations.c
+++ b/src/string_operations.c
@@ -1,6 +1,16 @@
#include <stdio.h>
#include <wchar.h>
+wchar_t *my_wstrchr(wchar_t *ws, wchar_t wc)
+
{
   +
   while (*ws) 
   {
      +
      if (*ws == wc)
      +
      return ws;
      +
      ++ws;
      + 
   }
   + return NULL;
   +
}
+
size_t my_wstrlen(const wchar_t *s)
{
   const wchar_t *p = s;

После проверки он фиксирует свои изменения.

[jerry@CentOS src]$ git status -s
M string_operations.c

[jerry@CentOS src]$ git add string_operations.c

[jerry@CentOS src]$ git commit -m 'Addded strchr function for wide character string'
[wchar_support 9d201a9] Addded strchr function for wide character string
1 files changed, 10 insertions(+), 0 deletions(-)

[jerry@CentOS src]$ git push origin wchar_support

Приведенная выше команда даст следующий результат –

Counting objects: 7, done.
Compressing objects: 100% (4/4), done.
Writing objects: 100% (4/4), 516 bytes, done.
Total 4 (delta 1), reused 0 (delta 0)
To gituser@git.server.com:project.git
3789fe8..9d201a9 wchar_support -> wchar_support

Разрешение конфликтов

Том хочет увидеть, что Джерри делает в своей частной ветке, поэтому он пытается получить последние изменения из ветки wchar_support, но Git прерывает операцию со следующим сообщением об ошибке.

[tom@CentOS src]$ git pull origin wchar_support

Приведенная выше команда дает следующий результат –

remote: Counting objects: 11, done.
63Git Tutorials
remote: Compressing objects: 100% (8/8), done.
remote: Total 8 (delta 2), reused 0 (delta 0)
Unpacking objects: 100% (8/8), done.
From git.server.com:project
* branch
wchar_support -> FETCH_HEAD
Auto-merging src/string_operations.c
CONFLICT (content): Merge conflict in src/string_operations.c
Automatic merge failed; fix conflicts and then commit the result.

Как разрешить конфликты

Из сообщения об ошибке видно, что существует конфликт в src/string_operations.c. Он запускает команду git diff, чтобы просмотреть дополнительные сведения.

[tom@CentOS src]$ git diff

Приведенная выше команда дает следующий результат –

diff --cc src/string_operations.c
index 52bec84,163a779..0000000
--- a/src/string_operations.c
+++ b/src/string_operations.c
@@@ -1,8 -1,17 +1,22 @@@
#include <stdio.h>
#include <wchar.h>
++<<<<<<< HEAD
+/* wide character strlen fucntion */
+size_t my_wc_strlen(const wchar_t *s)
++=======
+ wchar_t *my_wstrchr(wchar_t *ws, wchar_t wc)
+
{
   +
   +
   while (*ws) 
   {
      if (*ws == wc)
      +
      return ws;
      +
      ++ws;
      + 
   }
   + return NULL;
   +
}
+
+ size_t my_wstrlen(const wchar_t *s)
++>>>>>>>9d201a9c61bc4713f4095175f8954b642dae8f86
{
   const wchar_t *p = s;

Поскольку и Том, и Джерри изменили имя одной и той же функции, Git находится в замешательстве и просит пользователя разрешить конфликт вручную.

Том решает сохранить имя функции, предложенное Джерри, но оставил комментарий, добавленный им, как есть. После удаления маркеров конфликта git diff будет выглядеть так.

[tom@CentOS src]$ git diff

Приведенная выше команда дает следующий результат.

diff --cc src/string_operations.c
diff --cc src/string_operations.c
index 52bec84,163a779..0000000
--- a/src/string_operations.c
+++ b/src/string_operations.c
@@@ -1,8 -1,17 +1,18 @@@
#include <stdio.h>
#include <wchar.h>
+ wchar_t *my_wstrchr(wchar_t *ws, wchar_t wc)
+
{
   +
   while (*ws) 
   {
      +
      if (*ws == wc)
      +
      return ws;
      +
      ++ws;
      + 
   }
   + return NULL;
   +
}
+
+/* wide character strlen fucntion */
- size_t my_wc_strlen(const wchar_t *s)
+ size_t my_wstrlen(const wchar_t *s)
{
   const wchar_t *p = s;

Поскольку Том изменил файлы, он должен сначала зафиксировать эти изменения, а после этого он сможет их извлечь.

[tom@CentOS src]$ git commit -a -m 'Resolved conflict'
[master 6b1ac36] Resolved conflict

[tom@CentOS src]$ git pull origin wchar_support.

Том разрешил конфликт, теперь операция извлечения завершится успешно.

Разные платформы

РУССКИЙGNU / Linux и Mac OS используют перевод строки (LF) или новую строку в качестве символа конца строки, тогда как Windows использует комбинацию перевода строки и возврата каретки (LFCR) для представления символа конца строки.

Чтобы избежать ненужных коммитов из-за этих различий в конце строки, мы должны настроить клиент Git для записи того же окончания строки в репозиторий Git.

Для системы Windows мы можем настроить клиент Git для преобразования окончаний строк в формат CRLF при извлечении и преобразования их обратно в формат LF во время операции фиксации. Следующие настройки сделают необходимое.

[tom@CentOS project]$ git config --global core.autocrlf true

Для GNU / Linux или Mac OS мы можем настроить клиент Git для преобразования окончаний строк из CRLF в LF при выполнении операции проверки.

[tom@CentOS project]$ git config --global core.autocrlf input

Интернет-репозитории

GitHub – это веб-хостинг для проектов разработки программного обеспечения, использующий систему контроля версий Git. Он также имеет стандартное приложение с графическим интерфейсом, доступное для загрузки (Windows, Mac, GNU / Linux) непосредственно с веб-сайта службы. Но в этом сеансе мы увидим только часть CLI.

Создание репозитория GitHub

Зайдите на github.com. Если у вас уже есть учетная запись GitHub, войдите с помощью этой учетной записи или создайте новую. Следуйте инструкциям на сайте github.com, чтобы создать новый репозиторий.

Push операция

Том решает использовать сервер GitHub. Чтобы начать новый проект, он создает новый каталог и один файл внутри него.

[tom@CentOS]$ mkdir github_repo

[tom@CentOS]$ cd github_repo/

[tom@CentOS]$ vi hello.c

[tom@CentOS]$ make hello
cc hello.c -o hello

[tom@CentOS]$ ./hello

Приведенная выше команда даст следующий результат:

Hello, World !!!

После проверки своего кода он инициализирует каталог с помощью команды git init и фиксирует свои изменения локально.

[tom@CentOS]$ git init
Initialized empty Git repository in /home/tom/github_repo/.git/

[tom@CentOS]$ git status -s
?? hello
?? hello.c

[tom@CentOS]$ git add hello.c

[tom@CentOS]$ git status -s
A hello.c
?? hello

[tom@CentOS]$ git commit -m 'Initial commit'

После этого он добавляет URL-адрес репозитория GitHub в качестве удаленного источника и отправляет свои изменения в удаленный репозиторий.

[tom@CentOS]$ git remote add origin https://github.com/kangralkar/testing_repo.git

[tom@CentOS]$ git push -u origin master

Операция push запросит имя пользователя и пароль GitHub. После успешной аутентификации операция завершится успешно.

Приведенная выше команда даст следующий результат:

Username for 'https://github.com': kangralkar
Password for 'https://kangralkar@github.com': 
Counting objects: 3, done.
Writing objects: 100% (3/3), 214 bytes, done.
Total 3 (delta 0), reused 0 (delta 0)
To https://github.com/kangralkar/test_repo.git
 * [new branch]      master −> master
 Branch master set up to track remote branch master from origin.

С этого момента Том может отправлять любые изменения в репозиторий GitHub. Он может использовать все команды, обсуждаемые в этой главе, с репозиторием GitHub.

Pull операция

Том успешно отправил все свои изменения в репозиторий GitHub. Теперь другие разработчики могут просмотреть эти изменения, выполнив операцию клонирования или обновив свой локальный репозиторий.

Джерри создает новый каталог в своем домашнем каталоге и клонирует репозиторий GitHub с помощью команды git clone.

[jerry@CentOS]$ pwd
/home/jerry

[jerry@CentOS]$ mkdir jerry_repo

[jerry@CentOS]$ git clone https://github.com/kangralkar/test_repo.git

Приведенная выше команда дает следующий результат:

Cloning into 'test_repo'...
remote: Counting objects: 3, done.
remote: Total 3 (delta 0), reused 3 (delta 0)
Unpacking objects: 100% (3/3), done.

Он проверяет содержимое каталога, выполняя команду ls.

[jerry@CentOS]$ ls
test_repo

[jerry@CentOS]$ ls test_repo/
hello.c

Совершенствуй знания каждый день у нас в Телеграм-каналах

Вопросы, реклама — VK | Telegram