Синхронизация локального репозитория с GitHub
Локальный репозиторий можно синхронизировать с удаленным репозиторием при внесении изменений в любой из них. В Git удаленный — это сервер, на котором хранится код. В вашем случае этот сервер является репозиторием на GitHub или GitHub Enterprise.
Синхронизация ветви
Так как фиксации передаются в проект в GitHub, вы можете синхронизировать локальную копию проекта путем ее извлечения из удаленного репозитория.
Syncing with GitHub
So far you used Git to create a repository called hello-world on your own computer, but no one else can see those files. Next, you will use GitHub to share the contents of your repository so others can collaborate. This involves creating an empty repository in GitHub, then linking it to your local repository.
Create an empty GitHub repository
Log into your GitHub account and create a new repository by clicking the + icon in the upper-right corner of any page, then selecting New repository.
- Name the repository “hello-world”
- Add optional description
- Ensure repository is set to “Public”
- Click “Create repository”
Though not mandatory, choosing a license is an important part of openly sharing your creative work online. For help selecting an appropriate license see https://choosealicense.com/.
After creating the “hello-world” repository, GitHub will display the repository main web-page on your browser. This page contains information required to link your GitHub repository, remote , to the repository you created with Git on your own computer.
Linking your local repository to the GitHub repository (using SSH or HTTPS)
We need to set up a way for our local computer to authenticate with GitHub so that GitHub recognizes our computer as belonging to the same person who owns the GitHub repository.
GitHub removed password authentication on August 13, 2021. You have two options to connect your local machine to GitHub.
Option 1. Connecting with SSH

First, copy the URL from your GitHub repository. Move back to your shell application and enter the first command:
SSH Background and Setup
SSH is a security protocol widely used by many applications. You can use the following commands to connect your newly created repository or your existing repository to Github.
We will use SSH as our authentication method. SSH stands for Secure SHell protocol. SSH is a cryptographic network protocol that allows secure communication between computers using an otherwise insecure network.
What we will do now is the minimum required to set up the SSH keys and add the public key to a GitHub account.
## Advanced SSH —> A supplemental episode in this lesson discusses SSH and key pairs in more depth and detail.—>
The first thing we are going to do is check if this has already been done on the computer you’re on.
Keeping your keys secure
You shouldn’t really forget about your SSH keys, since they keep your account secure. It’s good practice to audit your secure shell keys every so often. Especially if you are using multiple computers to access your account.
We will run the list command ( ls ) to check what key pairs already exist on your computer. In our command we use the
as the shorthand for “my home directory.”
If you have not set up SSH, your output might look like this:
If SSH has been set up on the computer you’re using, the public and private key pairs will be listed. The file names are either id_ed25519 / id_ed25519.pub or id_rsa / id_rsa.pub depending on how the key pairs were set up.

If you do not have SSH set up, let’s set it up now. Use this command to create key pairs:
We want to use the default file, so just press Enter .
Your computer is now asking you for a passphrase to protect this SSH key pair. We recommend that you use a passphrase and that you make a note of it. There is no “reset my password” option for this setup. If you forget your passphrase, you have to delete your existing key pair and do this setup again. It’s not a big deal, but easier if you don’t have to repeat it.
After entering the same passphrase a second time, you will receive the confirmation
The “identification” is actually the private key. You should never share it. The public key is appropriately named. The “key fingerprint” is a shorter version of a public key.
Now we need to give our public key over to GitHub.
First, we need to copy the public key. Be sure to include the .pub at the end, otherwise you’re looking at the private key.
Copy that entire line of output, and we will paste the copied text into GitHub in the next step.
Now, going to GitHub.com, click on your profile icon in the top right corner to get the drop-down menu. Click “Settings,” then on the settings page, click “SSH and GPG keys,” on the left side “Account settings” menu. Click the “New SSH key” button on the right side. Now, you can add the title (A person might use the title “My 2021 work laptop,” just a little description to remind themselves which computer this public key connect to). Paste your SSH key into the field, and click the “Add SSH key” to complete the setup.
Now that we’ve set that up, let’s check our authentication from the command line.
Option 2. Connecting with HTTPS & GitHub Access Tokens
You can also use HTTPS protocol to connect your local repository to GitHub. Take a look at the following figure and find the commands you need to use to sync your local repository with Github. We will explain these commands in the rest of this section.

Now we are going to use the HTTPS protocol and GitHub access tokens (or Git Credential Manager, depending on your OS). GitHub access tokens are simple to obtain, but should be used with caution and should not be shared.
Step 1: link the repositories with “git remote add”
Enter the command below, replacing as appropriate.
This links your local Git repository to a remote one. The link indicates the location of the remote repository, which is nicknamed origin in this example. The nickname can be anything but Git convention is to refer to the remote repository as origin.
We can confirm that it is set up correctly with this command:
Step 2: synchronize the repositories with “git push”
The git push command can “push” our local content and tracking information to the GitHub repository, synchronizing the content. If you run git push right now, Git asks for your GitHub username and password. Even if you enter the correct username and password, the command will not work since support for password authentication was removed in 2021. To fix this error, you can use GitHub Access Tokens or use code editors that support API authentication. In this workshop, we use access tokens:
Step 3: Configure Access Token on GitHub
You can use token-based authentication when performing Git operations requiring authentication.
In the first step, we will create a personal Access Token on GitHub. Follow these steps to create one for your GitHub account:
- Click on your GitHub profile icon on the top right corner and click on Settings
- Choose Developer Settings on the menu on the left
- Click Personal access tokens and Generate new token
- Add a specific note that will help you identify the scope of the access token
- Choose the Expiration period from the drop down menu and select the scopes you want to grant the corresponding access to the generated access token. Make sure to select the minimum required scopes. For this workshop, public_repo should be enough.
- Click on Generate Token
Now, a new page is opened in which you can see your personal access token and copy it.
Now, we need to run the following command to use this access token:
Pushing the local repository
Now, we have successfully established a connection between the two repositories. To synchronize the content of the remote and local repositories, we will have to “push” our local changes to the GitHub repository.
The nickname of our remote repository is “origin” and the default local branch name is “main”. The -u flag tells git to remember these parameters, so that next time we can simply run git push and Git will know what to do.
When we do a git push we will see Git “pushing” changes to the specified remote repository — in this case, on GitHub. Because our file is small this happens instantly, but it may take longer if you made many changes or are adding a very large repository. The git status command will indicate the status after “pushing” is complete.
This output lets us know where we are working (the main branch). We can also see that we have no changes to commit, and you’ll find a copy of the “index.md” file in your GitHub “hello-world” repository.
If you add a readme file or license file to your GitHub repository, the commit on GitHub is ahead of your latest commit on the local main branch and you need to pull the latest changes to sync the two repositories:
Pulling changes
When working with others or on multiple computers we need a way to pull all the remote changes back into our local repository. We can see how this works by adding a file to our GitHub repository, then “pulling” that change back to our computer.
Near the bottom of the “hello-world” repository on GitHub, there is a button to “Add a README” file to your repository. Click the button, enter some text, then scroll to the bottom and click “Commit new file” (The default commit message will be “Create README.md”, which is fine for our purposes).
It is good practice to add a README file briefly describing what the project is about. If the README is in the root directory GitHub will automatically display it like a cover page for your repository.
After adding a README on GitHub your local repository is out-of-sync with the remote repository. Let’s fix that by pulling the remote changes into the local repository with git pull .
The output shows that we have fast-forwarded our local repository to include the file README.md. We could confirm this by entering the ls command.
This section introduces some basic git commands but there are many others that may be useful in more complex and collaborative projects. For a more detailed introduction see the online Software Carpentry course Version control with Git.
Git и Github. Простые рецепты
При разработке собственного проекта, рано или поздно, приходится задуматься о том, где хранить исходный код и как поддерживать работу с несколькими версиями. В случае работы на компанию, обычно это решается за вас и необходимо только поддерживать принятые правила. Есть несколько общеупотребимых систем контроля версий, и мы рассмотрим одну из самых популярных — это Git и сервис Github.
Система Git появилась, как средство управления исходными текстами в операционной системе Linux и завоевала множество поклонников в среде Open Source.
Сервис Github предоставляет хостинг (хранение) исходных текстов как на платной, так и на бесплатной основе. Это одна из крупнейших систем, которую любят Open Source пользователи. Основное отличие платной версии — это возможность создания частных репозиториев (хранилищ) исходных текстов и если вам скрывать нечего, то можете спокойно пользоваться бесплатной версией.
После того, как вы начали работу над проектом и написали какой-то работающий прототип, у вас появится желание сохранить результаты работы. Это так же может быть полезно в случае, если вы захотите продолжить работу на другом компьютере. Самое простое решение — это сохранить все на флешке. Этот вариант неплохо работает, но если есть подключение к интернету (а сейчас у кого его нет), то удобно воспользоваться системами Git/Github.
В этой статье будут описаны базовые сценарии использования систем Git/Github при работе над проектом в среде Linux с помощью командной строки. Все примеры проверялись на системе с Linux Ubuntu 14.04 и Git 1.9.1. Если вы пользуетесь другим дистрибутивом, то возможны отличия.
Создание локального репозитория
Предположим, что ваш проект находится в папке /home/user/project. Перед тем, как сохранять исходники, можно посмотреть, нет ли временных файлов в папке с проектом и по возможности их удалить.
Для просмотра папки удобно воспользоваться командой tree, которая покажет не только содержимое каждой папки, но и древовидную структуру директорий.
Часто временные файлы содержат специфические суффиксы, по которым их легко обнаружить и в последствии удалить. Для поиска таких файлов можно воспользоваться командой find. В качестве примера посмотрим, как найти все файлы, которые генерируются компилятором Python и имеют расширение .pyc
Переходим в папку с проектом /home/user/project:
И показываем список файлов с расширением .pyc:
Эта команда выведет список всех файлов с расширением .pyc в текущей директории и в ее поддиректориях. Для удаления найденных файлов, достаточно добавить ключ -delete к этой команде:
Очень рекомендуется не спешить и сразу ключ этот не добавлять. Первый раз вызвать команду для просмотра файлов и только убедившись, что в список не попало ничего полезного добавить ключ удаления.
Создадим локальный репозиторий в папке с проектом:
После выполнения этой команды появится новая папка с именем .git. В ней будет несколько файлов и поддиректориев. На данный момент система управления версиями еще не видит наших файлов.
Добавление файлов в локальный репозиторий
Для добавления файлов используется команда:
После выполнения команды, файл readme будет добавлен в систему управления версий (конечно если он уже был то этого в проекте). При добавлении файла генерируется хеш значение, которое выглядит примерно так:
Добавленные файлы хранятся в папке .git/objects/xx/yyyyyyyy, при этом первые 2 цифры хеша ипользуются для указания директории, а остальное хеш значение является именем файла. Наш добавленный файл будет находится здесь:
Что легко увидеть с помощью команды:
Сам файл является архивом, который легко распаковать и вывести на экран, указав полное значение хеша.
Для того, чтобы добавить все файлы из текущей директории введите:
Если нужно добавить файлы из текущей директории и из всех поддиректориев, то используйте:
Для того, чтобы в систему не попадали временные файлы, можно их занести в файл .gitignore, который нужно создать самостоятельно и разместить в корневом каталоге проекта (на том же уровне, что и .git директория).
Например, если в в файл .gitignore добавить следующую строчку *.pyc, то все файлы с расширением .pyc не будут добавляться в репозиторий.
После добавления файлов, все изменения находятся в так называемой staging (или cached) area. Это некоторое временнное хранилище, которое используется для накопления изменений и из которого создаются собственно версии проектов (commit).
Для просмотра текущего состояния можно воспользоваться командой:
После выполнения команды мы увидим, что в stage area находится наш файл:
Если вы продолжите вносить изменения в файл readme, то после вызова команды git status вы увидите две версии файла.
Чтобы добавить новые изменения достаточно повторить команду. Команда git add не только добавляет новые файлы, но и все изменения файлов, которые были добавлены ранее.
Можно отменить добавления файла readme в staging area с помощью команды:
После выполнения команды, файл readme отметится, как неизмененный системой.
Создание версии проекта
После того, как мы добавили нужные файлы в staging area мы можем создать версию проекта. С помощью команды:
Каждая новая версия сопровождается комментарием.
После коммита, мы сможем найти два новых объекта внутри .git репозитория.
Посмотрим, что внутри:
Ключ -t показывает тип объекта. В результате мы видим:
Для второго объекта:
Для самого первого файла:
Если мы будем дальше изучать содержимое этих файлов, то обнаружим древовидную структуру. От каждого коммита можно по ссылкам пройти по всем измененным файлам. Для практического применения это не очень нужно, но возможно так будет легче понять, что происходит при работе с системой Git.
Самую первую версию отменить нельзя. Ее можно только исправить. Если вы хотите добавить изменения в последнюю версию, то после выполнения команды commit, добавляете необходимые изменения и вызываете:
Ключ —no-edit нужен, чтобы не вводить заново комментарий.
Можно просмотреть изменения, которые вы внесли последним коммитом:
Ключ —name-only нужен, чтобы показывать только имена измененный файлов. Без него по каждому измененнному файлу будет выдан список всех изменений.
Если вы продолжили работать и изменили только те файлы, которые были уже добавлены в систему командой git add, вы можете сделать коммит одной командой:
Для просмотра списка всех коммитов, воспользуйтесь командой:
Ключ —oneline нужен, чтобы уменьшить количество информации выдаваемой на экран. С этим ключем каждый коммит показывается в одну строчку. Например:
Для того, чтобы просмотреть изменения по конкретному коммиту, достаточно в команду git show добавить хеш значение коммита, которое можно получить с помощью предыдущей команды.
Для отмены последнего коммита (кроме самого первого) можно воспользоваться следующей командой:
Для того чтобы удалить все файлы в папке, которые не относятся к проекту и не сохранены в репозитории, можно воспользоваться командой:
Создание репозитория на Github
До текущего момента мы работали с локальным репозиторием, который сохранялся в папке на компьютере. Если мы хотим иметь возможность сохранения проекта в интернете, создадим репозиторий на Github. Для начала нужно зарегистрироваться на сайте github.com под именем myuser (в вашем случае это может быть любое другое имя).
После регистрации нажимаем кнопочку «+» и вводим название репозитория. Выбираем тип Public (репозиторий всегда Public для бесплатной версии) и нажимаем Create.
В результате мы создали репозиторий на сайте Github. На экране мы увидим инструкцию, как соединить наш локальный репозиторий со вновь созданным. Часть команд нам уже знакома.
Добавляем удаленный репозиторий (по протоколу SSH) под именем origin (вместо origin можно использовать любое другое имя).
Можем просмотреть результат добавления с помощью команды:
Если все было правильно сделано, то увидим:
Для того, чтобы отменить регистрацию удаленного репозитария введите:
Это может понадобиться, если вы захотите поменять SSH доступ на HTTPS. После этого можно добавить его опять, например под именем github и протоколом HTTPS.
Следующей командой вы занесете все изменения, которые были сделаны в локальном репозитории на Github.
Ключ -u используется для того, чтобы установить связь между удаленным репозиторием github и вашей веткой master. Все дальнейшие изменения вы можете переносить на удаленный репозиторий упрощенной командой.
Перенос репозитория на другой компьютер
После того, как репозиторий был создан на Github, его можно скопировать на любой другой компьютер. Для этого применяется команда:
Результатом выполнения этой команды будет создание папки project в текущем каталоге. Эта папка также будет содержать локальный репозиторий (то есть папку .git).
Так же можно добавить название папки, в которой вы хотите разместить локальный репозиторий.
Работа с одним репозиторием с разных компьютеров
С одним репозиторием с разных компьютеров может работать несколько разработчиков или вы сами, если например работаете над одним и тем же проектом дома и на работе.
Для получения обновлений с удаленного репозитория воспользуйтесь командой:
Если вы изменили ваши локальные файлы, то команда git pull выдаст ошибку. Если вы уверены, что хотите перезаписать локальные файлы, файлами из удаленного репозитория то выполните команды:
Вместо github подставьте название вашего удаленного репозитория, которое вы зарегистрировали командой git push -u.
Как мы уже знаем, для того чтобы изменения выложить на удаленный репозиторий используется команда:
В случае, если в удаленном репозитории лежат файлы с версией более новой, чем у вас в локальном, то команда git push выдаст ошибку. Если вы уверены, что хотите перезаписать файлы в удаленном репозитории несмотря на конфликт версий, то воспользуйтесь командой:
Иногда возникает необходимость отложить ваши текущие изменения и поработать над файлами, которые находятся в удаленном репозитории. Для этого отложите текущие изменения командой:
После выполнения этой команды ваша локальная директория будет содержать файлы такие же, как и при последнем коммите. Вы можете загрузить новые файлы из удаленного репозитория командой git pull и после этого вернуть ваши изменения которые вы отложили командой:
Синхронизация Git-репозиториев в режиме реального времени
Работая с клиентами на таких платформах, как Github или Gitlab, мы в Gitstart часто сталкиваемся с необходимостью синхронизировать кодовые базы между удаленными репозиториями. По каждой поставленной клиентом задаче наши разработчики работают внутри ветви частного репозитория (клона или форка клиентского репозитория), и необходима уверенность, что состояние клиентского репозитория соответствует нашему, как и наоборот. Со временем синхронизация репозиториев становится повторяющимся процессом, поэтому имеет смысл его как-то автоматизировать.
Встречайте Gitstart Fork: это наш внутренний инструмент, который использует мощь веб-хуков, чтобы синхронизировать код между парой репозиториев практически в реальном времени.
Но, спросите вы, как это работает? Чтобы упростить кодовую базу, мы решили разделить функциональность на две части:
- Pull : перемещение изменений из клиентского репозитория в наш репозиторий.
- Push : перемещение изменений из нашего репозитория в клиентский репозиторий.
В этой статье мы сосредоточимся на обсуждении Pull .
Стек технологий: большую часть кода мы пишем на TypeScript и Nodejs. В качестве базы данных мы выбрали PostgreSQL с Hasura в качестве движка GraphQL (там есть изящная функция под названием подписка, которая упрощает обработку).
Для простоты мы будем говорить о репозиториях Github, однако написанное можно распространить на любой удаленный сервис на основе git, к примеру Gitlab или Bitbucket.
1. Функции
Fork Pull предоставляет следующий функционал для синхронизации:
- Управление ветвями: укажите, какие именно ветви нужно синхронизировать.
- Детализированное управление синхронизацией файлов: укажите, какие именно папки/файлы будут синхронизированы, а какие — нет.
- Поддержка.gitignore : синхронизация не затронет файлы, перечисленные в .gitignore .
2. База данных
Всё начинается с таблицы, где отслеживаются оба синхронизируемых репозитория: какие ветви синхронизировать в этих репозиториях, а также любые файлы или папки, которые синхронизировать не нужно. Высокоуровневая схема будет выглядеть следующим образом:
Мы также ведем учет всех так называемых “извлечений” ( pull ), которые мы сделали:
Эта таблица служит промежуточным звеном между началом и окончанием pull ’а. Мы в основном используем его для отслеживания хода извлечения. Так можно оценить успех или неудачу pull , узнать о произошедших ошибках, рассчитать необходимое для операции время и многое другое.
Успешный pull регистрируется в третьей таблице, которая отслеживает пару головных коммитов синхронизированных ветвей (важность этой таблицы станет ясна в следующем разделе):
Примечание: все схемы здесь даны исключительно для того, чтобы создать общее представление. Поля можно как включать, так и исключать, в зависимости от желаемой функциональности.
3. Отслеживание изменений
База данных — это отлично, но как мы определяем, когда нужно делать pull ? В конце концов, это самая важная часть инструмента, который претендует на “работу в реальном времени”. Вот где проявляется магия веб-хуков и подписок Hasura! У нас в Gistart уже создана довольно надежная и масштабируемая инфраструктура веб-хуков. Вкратце ее можно резюмировать так:
- Все веб-хуки со сторонних сервисов, таких как Github или Jira, хранятся в нашей базе данных.
- Впоследствии эти веб-хуки обрабатываются и соответствующие таблицы обновляются соответствующим образом.
- Если обработка любой полезной нагрузки веб-хука не удается, мы ждем 5 минут, прежде чем повторить попытку.
Для наших целей нужно сосредоточиться только на одном типе событий Github: push . Это событие происходит всякий раз, когда один или несколько коммитов помещаются в ветку или тэг репозитория.
Это вебхук-событие мы объединяем с щепоткой магии подписок и получаем такую последовательность событий для обнаружения изменений:
- Коммиты передаются в наше хранилище исходного кода fromRepo .
- Веб-хук push регистрируется в базе данных и обрабатывается.
- Это изменяет головной коммит SHA-1 исходной ветви в нашей базе данных.
- Как только база данных обновляется, подписка (см. GraphQL-код ниже) замечает, что ветвь основного репозитория содержит новые коммиты, которые еще не были извлечены, и запускает в соответствии с этим обработчик:
- Затем код выполняет pull и репозитории синхронизируются (подробнее об этом в следующем разделе).
Основным триггером события pull служит обновление базы данных. В нашем случае это достигается с помощью веб-хуков благодаря их способности реагировать в реальном времени. Однако того же самого результата можно добиться и через ряд других вариантов.
Внимание: следующие шаги предполагают, что база данных актуализирована.
4. Архитектура Git
И здесь начинается настоящее веселье. На самом деле, выполнить pull не очень сложно. В качестве клиента git мы используем isomorphic-git. Операции git можно разделить на 5 этапов:
4.1 Клонирование ( clone )
Репозитории мы клонируем во временные папки. Если такие папки уже существуют, мы просто извлекаем последние коммиты и переключаемся на интересующие нас ветви. Ни удаления папок, ни повторного клонирования каждый раз не происходит, потому что pull производится быстрее, чем клонирование.
4.2 Удаление (delete)
В целях синхронизации мы убираем и удаляем из индекса git все файлы/папки, присутствующие в toRepo , но не в fromRepo , следя за тем, чтобы исключить игнорируемые файлы/папки. Для этого мы применяем glob matching (глобальное сопоставление): определяем разницу между наборами путей к файлам и удаляем их:
4.3 Копирование (copy)
Теперь мы копируем все файлы из fromRepo в toRepo с помощью легкой библиотеки copy-dir . Эта библиотека предоставляет фильтр для фильтрации путей к файлам, что в нашем случае полезно:
4.4 Добавление и коммит (Add & commit)
Простой шаг, на котором мы добавляем все пути к файлам в будущий коммит (стейджинг) и делаем коммит, получая SHA-1 головного коммита для нужд базы данных.
4.5 Отправление (push)
Наконец мы отправляем коммиты в наш toBranch . Этот push вызовет веб-хук, который мы впоследствии обработаем ради сохранения целостности нашей базы данных.
5. Заключение
И вот, репозитории наконец-то синхронизированы!
Это похоже на волшебство, но именно так оно и ощущается, когда технология используется изящно и с умом.