Архив рубрики: Git

Установка в Linux Mint 18.3 различных инструментов, используемых для программирования

Мне не нравится современный пользовательский интерфейс Linux Ubuntu, но в то же время мне нравится более классический интерфейс Linux Mint 18.3, построенной (согласно официальной информации) на базе Ubuntu 16.04. Поэтому на моём ноутбуке установлен Linux Mint 18.3.

Поскольку меня интересует программирование на языках C, C#, JavaScript и Java, то в данной заметке я размещаю краткую шпаргалку о том, какой софт можно установить в Linux Mint 18.3 для возможности разработки софта с использованием упомянутых выше языков программирования.

GCC

В качестве компилятора для языка C я конечно же предпочитаю использовать gcc. К сожалению, по умолчанию, в Linux Mint 18.3 установлена весьма старая (5-я) версия этого компилятора. Информацию о версии установленной у вас версии gcc всегда можно получить так:

gcc --version

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

На всякий случай дублирую содержимое ссылки, дабы в случае удаления кем-либо указанной выше информации она бы не была безвозвратно утеряна:

These commands are based on a askubuntu answer http://askubuntu.com/a/581497 and https://askubuntu.com/questions/26498/choose-gcc-and-g-version
To install gcc-7 (gcc-7.2.0), I had to do more stuff as shown below.
USE THOSE COMMANDS AT YOUR OWN RISK. I SHALL NOT BE RESPONSIBLE FOR ANYTHING.
ABSOLUTELY NO WARRANTY.

If you are still reading let's carry on with the code.

sudo apt-get update && \
sudo apt-get install build-essential software-properties-common -y && \
sudo add-apt-repository ppa:ubuntu-toolchain-r/test -y && \
sudo apt-get update && \
sudo apt-get install gcc-snapshot -y && \
sudo apt-get update && \
sudo apt-get install gcc-7 g++-7 gcc-6 g++-6 gcc-multilib -y && \
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-7 70 --slave /usr/bin/g++ g++ /usr/bin/g++-7 && \
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-6 60 --slave /usr/bin/g++ g++ /usr/bin/g++-6 && \
sudo apt-get install gcc-5 g++-5 -y && \
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-5 50 --slave /usr/bin/g++ g++ /usr/bin/g++-5;

When completed, you must change to the gcc you want to work with by default. Type in your terminal:
sudo update-alternatives --config gcc

To verify if it worked. Just type in your terminal
gcc -v

If everything went fine you should see gcc 7.2.0 by the time I am writing this gist

Happy coding!

See blog post at https://www.application2000.com

Помимо того, что gcc можно использовать непосредственно из консоли, его так же используют и различного рода IDE, например, используемый мною CLion компании JetBrains. Эта IDE позволяет писать на C90, С99 и даже С11, в отличии от  той жеVisual Studio, позволяющей писать только на  C90. 

VIM & IDE

В качестве текстового редактора я предпочитаю vim. Это приложение особенно полезно для тех, кто владеет слепой десятипальцевой печатью, которой можно обучиться, например, на сайте Владимира Шахиджаняна:  https://solo.nabiraem.ru/ - свои навыки я когда-то получил именно там.

Компания JetBrains предоставляет набор кроссплатформенных IDE для интересующих меня языков программирования:
Для каждого из этих редакторов присутствует возможность установить плагин IdeaVim, позволяющий эмулировать vim в качестве текстового редактора IDE. Т.о. навыки использования vim могут быть успешно использованы в используемых мною IDE.

Установка vim:

sudo apt-get install vim

Проверка установленной версии vim:

vim --version

Краткая обучающая инструкция по базовым основам использования vim:

vimtutor

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

sudo tar -xzf your.tar.gz -C /opt

В результате приложение будет установлено в каталог /opt.

Visual Studio Code

На официальном сайте Майкрософт можно скачать и установить самый свежий дистрибутив данного кроссплатформенного текстового редактора.

Среди доступных плагинов для этого текстового редактора так же имеется большой набор эмуляторов vim.

Atom

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

Для него так же можно скачать плагин эмуляции vim, как описано здесь:

apm install vim-mode-plus

Git

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

JDK

SDK для Java. На официальном сайте можно скачать и установить самую свежую версию JDK, необходимую для разработки кода на Java. Установленный JDK будет использоваться в IntelliJ Idea.

Node.js

Платформа, предоставляющая возможность разрабатывать приложения на JavaScript. С официального сайта устанавливать лучше LTS-версию. При установке Node.js автоматически будет установлен и менеджер пакетов NPM

NPM можно использовать не только для JavaScript, но и в проектах ASP.NET Core MVC 2.

.NET Core SDK

На официальном сайте Майкрософт присутствует подробная инструкция по установке самой свежей версии .NET Core SDK для Linux Ubuntu 16.04, на основе которой создан Linux Mint 18.3.

xUnit

Платформа для разработки модульных тестов для .NET и .NET Core. На официальном сайте даются ссылки на соответствующие NuGet и MyGet пакеты.

Хостинг ASP.NET Core 2 приложений в IIS

На тот случай, если своё web-приложение вы захотите хостить на IIS, компания Майкрософт опубликовала подробную инструкцию по данной теме. Особое внимание следует обратить на то, что на указанной странице, в разделе Установка пакета размещения .NET Core для Windows Server, указан пакет, который необходимо установить на сервере, чтобы IIS научился работать с вашим приложением.

Remmina

Это приложение удобно использовать в качестве RDP-клиента для удалённого подключения к компьютерам, работающим под управлением Windows.

VMWare Horizon Client

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

MS SQL Server 2017

Всю необходимую информацию по теме можно найти на официальном сайте продукта.

PowerShell Core

Наличие возможности использовать PowerShell в Linux является весьма удобной  для тех, кто привык пользоваться этой командной оболочкой в Windows. Например, для тестирования контроллеров API в ASP.NET Core MVC 2 можно воспользоваться привычной командой Invoke-RestMethod.

Инструкция по установке - на официальном сайте здесь.

UPD
Ниже написал небольшой скрипт, с помощью которого оперативно установил интересующий меня набор приложений:

#!/bin/bash
# (c) Андрей Бушман, 2018
# Данный скрипт устанавливает набор необходимого мне программного обеспечения.

sudo apt-get update
sudo apt-get upgrade

# Remmina
sudo apt-add-repository ppa:remmina-ppa-team/remmina-next
sudo apt-get update
sudo apt-get install remmina remmina-plugin-rdp remmina-plugin-secret

# VMware Horizon Client v4.7.0-7395152
wget -O ./vmware.x64.bundle https://download3.vmware.com/software/view/viewclients/CART18FQ4/VMware-Horizon-Client-4.7.0-7395152.x64.bundle
chmod +x ./vmware.x64.bundle
sudo ./vmware.x64.bundle

# Skype
wget -O skype.deb https://go.skype.com/skypeforlinux-64.deb
sudo dpkg --install ./skype.deb

# Git
sudo add-apt-repository ppa:git-core/ppa
sudo apt update; apt install git

git config --global user.name "Andrey Bushman"
git config --global user.email bushman.andrey@gmail.com
git config --global core.editor "vim"

# Google Chrome
wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb
sudo dpkg -i google-chrome-stable_current_amd64.deb

# GCC v7.3.0
sudo apt-get update && \
sudo apt-get install build-essential software-properties-common -y && \
sudo add-apt-repository ppa:ubuntu-toolchain-r/test -y && \
sudo apt-get update && \
sudo apt-get install gcc-snapshot -y && \
sudo apt-get update && \
sudo apt-get install gcc-7 g++-7 gcc-6 g++-6 gcc-multilib -y && \
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-7 70 --slave /usr/bin/g++ g++ /usr/bin/g++-7 && \
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-6 60 --slave /usr/bin/g++ g++ /usr/bin/g++-6 && \
sudo apt-get install gcc-5 g++-5 -y && \
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-5 50 --slave /usr/bin/g++ g++ /usr/bin/g++-5;
sudo update-alternatives --config gcc

# VIM
git clone https://github.com/vim/vim.git
cd vim
git pull
cd vim/src
sudo apt-get install libncurses5-dev libncursesw5-dev
# make distclean  # if you build Vim before
make
sudo make install

# .Net Core 2.1.200 SDK
wget -q packages-microsoft-prod.deb https://packages.microsoft.com/config/ubuntu/16.04/packages-microsoft-prod.deb
sudo dpkg -i packages-microsoft-prod.deb

sudo apt-get install apt-transport-https
sudo apt-get update
sudo apt-get install dotnet-sdk-2.1.200

# Visual Studio Code
curl https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor > microsoft.gpg
sudo mv microsoft.gpg /etc/apt/trusted.gpg.d/microsoft.gpg
sudo sh -c 'echo "deb [arch=amd64] https://packages.microsoft.com/repos/vscode stable main" > /etc/apt/sources.list.d/vscode.list'
sudo apt-get update
sudo apt-get install code # or code-insiders

# Sublime Text 3
wget -qO - https://download.sublimetext.com/sublimehq-pub.gpg | sudo apt-key add -
sudo apt-get install apt-transport-https
echo "deb https://download.sublimetext.com/ apt/stable/" | sudo tee /etc/apt/sources.list.d/sublime-text.list
sudo apt-get update
sudo apt-get install sublime-text


# Atom
curl -L https://packagecloud.io/AtomEditor/atom/gpgkey | sudo apt-key add -
sudo sh -c 'echo "deb [arch=amd64] https://packagecloud.io/AtomEditor/atom/any/ any main" > /etc/apt/sources.list.d/atom.list'
sudo apt-get update
sudo apt-get install atom

# JDK 10.0.1
wget https://download.java.net/java/GA/jdk10/10.0.1/fb4372174a714e6b8c52526dc134031e/10/openjdk-10.0.1_linux-x64_bin.tar.gz
sudo tar xvf openjdk-10.0.1_linux-x64_bin.tar.gz -C /opt

# NodeJS v8.11.1
wget -O node.tar.gz https://nodejs.org/dist/v8.11.1/node-v8.11.1-linux-x64.tar.xz
sudo tar xf ./node.tar.gz -C /opt

# JetBrains Clion 2018.1.2
wget -O ./CLion.tar.gz http://download.jetbrains.com/cpp/CLion-2018.1.2.tar.gz
sudo tar xvf CLion.tar.gz -C /opt

# JetBrains IntelliJ IDEA 2018.1.3
wget -O ./intellij.tar.gz http://download.jetbrains.com/idea/ideaIU-2018.1.3.tar.gz
sudo tar xfz ./intellij.tar.gz -C /opt

# JetBrains Rider 2018.1
wget -O ./rider.tar.gz http://download.jetbrains.com/rider/JetBrains.Rider-2018.1.tar.gz
sudo tar xfz ./rider.tar.gz -C /opt

# JetBrains WebStorm 2018.1.3
wget -O ./webstorm.tar.gz http://download.jetbrains.com/webstorm/WebStorm-2018.1.3.tar.gz
sudo tar xfz ./webstorm.tar.gz -C /opt

# JetBrains Pycharm 2018.1.2
wget -O ./pycharm.tar.gz http://download.jetbrains.com/python/pycharm-professional-2018.1.2.tar.gz
sudo tar xfz ./pycharm.tar.gz -C /opt

# JetBrains DataGrip 2018.1.2
wget -O ./datagrip.tar.gz http://download.jetbrains.com/datagrip/datagrip-2018.1.2.tar.gz
sudo tar xfz ./datagrip.tar.gz -C /opt

# JetBrains GoLand 2018.1.2
wget -O ./goland.tar.gz http://download.jetbrains.com/go/goland-2018.1.2.tar.gz
sudo tar xfz ./goland.tar.gz -C /opt

# Python v3.6.5
wget -O ./python.tar.xz https://www.python.org/ftp/python/3.6.5/Python-3.6.5.tar.xz
tar xf ./python.tar.xz
cd ./Python-3.6.5
./configure
make
make test
sudo make install

# MS SQL Server 2017
sudo curl https://packages.microsoft.com/keys/microsoft.asc | sudo apt-key add -
sudo add-apt-repository "$(curl https://packages.microsoft.com/config/ubuntu/16.04/mssql-server-2017.list)"
sudo apt-get update
wget -qO- https://packages.microsoft.com/keys/microsoft.asc | sudo apt-key add -
sudo add-apt-repository "$(wget -qO- https://packages.microsoft.com/config/ubuntu/16.04/mssql-server-2017.list)"
sudo apt-get update
sudo apt-get install -y mssql-server
sudo /opt/mssql/bin/mssql-conf setup

systemctl status mssql-server 

# MS SQL Server Tools
curl https://packages.microsoft.com/keys/microsoft.asc | sudo apt-key add -
curl https://packages.microsoft.com/config/ubuntu/16.04/prod.list | sudo tee /etc/apt/sources.list.d/msprod.list
sudo apt-get update 
sudo apt-get install mssql-tools unixodbc-dev

sudo apt-get update 
sudo apt-get install mssql-tools

echo 'export PATH="$PATH:/opt/mssql-tools/bin"' >> ~/.bash_profile

echo 'export PATH="$PATH:/opt/mssql-tools/bin"' >> ~/.bashrc
source ~/.bashrc

# Docker CE 17.03
sudo apt-get update
sudo apt-get install -y apt-transport-https ca-certificates curl software-properties-common
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
sudo add-apt-repository "deb https://download.docker.com/linux/$(. /etc/os-release; echo "") $(lsb_release -cs) stable"
sudo apt-get update && sudo apt-get install -y docker-ce=$(apt-cache madison docker-ce | sudo grep 17.03 | sudo head -1 | sudo awk '{print }')

# Kibernetes
sudo apt-get update && sudo apt-get install -y apt-transport-https curl
curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add -
cat <<EOF >/etc/apt/sources.list.d/kubernetes.list
deb http://apt.kubernetes.io/ kubernetes-xenial main
EOF
sudo apt-get update
sudo apt-get install -y kubelet kubeadm kubectl

sudo docker info | sudo grep -i cgroup
cat /etc/systemd/system/kubelet.service.d/10-kubeadm.conf
sudo sed -i "s/cgroup-driver=systemd/cgroup-driver=cgroupfs/g" /etc/systemd/system/kubelet.service.d/10-kubeadm.conf

systemctl daemon-reload
systemctl restart kubelet

# PowerShell Core
sudo apt-get install -y powershell


Устанавливаем, настраиваем и начинаем работаь с Git

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

Установка
Скачать последнюю версию дистрибутива для Windows можно здесь. Ставил в режиме далее-далее-далее. Если будут какие то особенности, то потом допишу.

Настройка
Прописать имя пользователя и почту в настройки пользователя:
$ git config --global user.name "Alexey Losev"
$ git config --global user.email myemail@domen.ru
Кроме --global (настройки текущего пользователя), есть еще --system (системные настройки) и без ключа, это значит настройки текущего репозитария.
Проверить что все записалось нормально, можно командами:
$ git config --global user.email
$ git config --global user.name
Или даже:
$ git config user.email
$ git config user.name
Ну или все настройки доступны командой:
$ git config --list

Справка
Получить справку по команде можно командами:
$ git config --global user.email
$ git config --global user.name
Справка выполнена в виде html, которые при установке сохраняются на диск и доступна без подключения к интернету.
Кстати, команда:
$ man git-<команда>
В Windows не работает.

Создание репозитория
Для путешествия по папкам через Git Bush можно пользоваться стандартными досовскими командами (cd, dir). Только вот есть пара отличий:
1. При переходе на другой диск необходимо вместо d:/ писать /d/
2. Восклицательный знак в пути - это проблема
Ну а так, все стандартно:
$ cd /d/git/robotsbattle
$ dir

Все, создаем репозиторий:
$ git init
Для добавления в репозиторий существующих файлов можно воспользоваться командой:
$ git add *.sln
Фиксация изменений происходит командой
$ git commit -m 'комментарий к коммиту'
Получение того, что у нас твориться в репозитории:
$ git status
Чтобы посмотреть не просто список, а что изменилось в файлах, можно вызвать:
$ git diff
Получим аналог Create Patch из SVN. Пример как это работает:
У команды git diff, есть модификация:
$ git diff --cached
Которая позволяет понять одну магию. В коммит попадают только проиндексированные файлы. Т.е. если файл изменился, то для того, чтобы он попал в коммит его необходимо проиндексировать командой 
add:
$ git add RobotsBattle/Cell.cs
И здесь есть тонкость, хотя Windows игнорирует регистр символов, а вот Git Bash - нет. Т.е. предыдущая команда отработает корректно, а вот эта нет:
$ git add robotsbattle/cell.cs
После добавления файла в кэш, git diff без ключей его игнорирует, а вот указанный ключ 
--cached позволяет посмотреть, что же мы закешировали.
Если заниматься индексацией каждый раз не хочется, то можно вызвать коммит для всех измененных файлов не зависимо от того, закешированы они или нет следующей командой:
$ git commit -a -m "Добавлен комментарий"
Ну и так как у нас в папках проектов всегда есть файлы, которые добавлять в хранилище не надо, то можно создать файл с расширением  .gitignore 
К шаблонам в файле .gitignore применяются следующие правила:
  • Пустые строки, а также строки, начинающиеся с #, игнорируются.
  • Можно использовать стандартные glob-шаблоны.
  • Можно заканчивать шаблон символом слэша (/) для указания каталога.
  • Можно инвертировать шаблон, использовав восклицательный знак (!) в качестве первого символа.
Вот так может выглядеть этот файл, чтобы игнорировать файлы и папки начинающиеся с точки, а также папке bin и obj в первом уровне вложенности относительно корня:

Glob — шаблоны в .gitignore

Для определения какие файлы в папке должны игнорироваться git-ом, создается файл .gitignore. В котором применяются glob - шаблоны. То что под катом, это краткая дока по glob-шаблонам для тех, кто не работает в *nix системах. Т.е. для меня.

Начну с того, что строка может содержать имя файла или директории. В этом случае шаблоном она являться не будет. Например, если у меня в папке с решением лежит папка .vs, то я могу в файле .gitignore прямо так и написать .vs. И эта папка будет игнорироваться.
Glob шаблоном является строка содержащая один из символов "?", "*" или "[".
"?", "*" пока они не в квадратных скобках работают весьма привычно. "?" - любой символ, "*" - любая последовательность символов. А вот квадратные скобки задают классы символов.
Класс символов позволяет задать что на этой позиции будет находится символ принадлежащий классу или (если после открывающейся скобки идет восклицательный знак "!") не принадлежащий классу.
Классы задаются перечислением, либо диапазонами.
[abc] - любой из символов a, b, c.
[a-c] - любой из символов находящихся между a и c. Т.е. те же три символа a, b, c.
[a-c1-3] - любой из символов a, b, c или цифра от 1 до 3.
[!abc] - любой символ кроме букв a, b, c.
Если в класс должны входить закрывающаяся скобка "]", то она должна идти первой в классе:
[]a-c] - закрывающаяся скобка или любой из символов a, b, c.
Если в классе необходимо использовать "-" именно как символ, то он должен стоять на первой или последней позиции.
[]-] - соответствует двум символам: "]" и "-"
[--/] - соответствует  трем символами: "-", "." и "/".
Ну и пара примеров.
Игнорируем все что начинается с точки (файлы и папки):
В папках RobotsBattle и RobotsBattleConsole есть папки bin и debug. Мне эти папки надо исключить:

На BitBucket опубликованы исходники проекта по работе с proxy в AutoCAD

Закинул в свой профиль на BitBucket исходники проекта по работе с прокси в AutoCAD. Проект в открытом доступе. Там же опубликован и результат компиляции.

UPD (27.06.2016) Программа переведена из категории открытой в категорию бесплатной. Отныне доступны MSI-инсталляторы, но не исходный код. Подробнее здесь.

Издательство "Питер" представило русский перевод книги Pro Git 2.

На днях издательство "Питер" представило перевод книги Pro Git 2. В англоязычном варианте книга имеется в свободном доступе (официальный сайт книги здесь). Да, я в курсе о том, что группой энтузиастов давно выполняется её перевод, но судя по текущему состоянию этого перевода - он не сильно продвинулся с тех пор, как я смотрел его в последний раз весной (во всяком случае ряд интересующих меня тем так и не переведён до сих пор). К сожалению, издательство "Питер" продаёт только электронную версию книги (epub, pdf). Кроме того, за электронную версию 400 рублей - это несколько завышенная цена (на мой взгляд). Покупать или нет - это уж каждый пусть решает для себя сам.

Некоторые мысли по поводу заметки Алексея Кулика о Git.

Опубликовываю последовательность действий, оформленных в виде скрипта, согласно тому, как обещал в комментариях здесь. Как я уже писал, изложенный в ссылке пример совместной работы, на мой взгляд, является, к сожалению, плохим. Я считаю, что Алексей показал даже скорее пример того, как НЕ НАДО делать (буду называть вещи своими именами), т.к. работая с Git использовать стиль работы Subversion - это значит ограничивать себя (ИМХО). :((( Тем, кому интересна тема коллективной работы с использованием Git настоятельно рекомендую прочесть эту главу.

UPD: Добавляю информацию о такой новости.

Алексей в своём примере использовал  "традиционный" подход к организации рабочего процесса, использующийся во многих централизованных системах контроля версий (таких как Subversion). Данный подход называется централизованным рабочим процессом. Его можно использовать и в Git, но т.к. Git является распределённой системой контроля версий, то это даёт возможность использовать и более "продвинутые" подходы, такие как рабочий процесс с менеджером по интеграции или же рабочий процесс с диктатором и его помощниками. Я считаю, что использовать в Git централизованный рабочий процесс - это всё равно, что ходить на работу в ластах несмотря на то, что в наличии имеются отличные ботинки.

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

Ещё мне очень не понравилось то, что в своём примере Алексей заливал в центральный репозиторий не конечный результат работы пользователей, а каждый их "чих" (т.е. промежуточные состояния веток, не являющихся основными и в конечном счёте подлежащие слитию с веткой master). Я считаю, что в центральном репозитории должна храниться стабильная ("устаканившаяся") версия проектов. А все коммиты и ветки, предшествующие появлению этой самой стабильной версии заливать в центральный репозиторий не следует (для этого у каждого девелопера должны быть собственные рабочий и публичный репозитории), т.к. это его замусоривает. Делая git fetch я не хочу видеть разнообразие посторонних веток (находящихся на различных промежуточных стадиях разработки), которые туда напихали др. программисты. Мне (да наверное и всем остальным) не хочется заливать себе в репозиторий весь этот лишний (поскольку не мой) набор дополнительных, промежуточных веток, над которыми я не работаю. Когда девелоперы доделают свою работу, то зальют результат в основную ветку - именно этот самый конечный результат мне интересен, когда я заливаю себе код с центрального репозитория.

А для того, чтобы test1 мог тестировать ветки юзеров dev1 и dev2, они просто дают ему ссылки на свои public репозитории и говорят, какие ветки нужно протестировать. test1 спокойно тестирует эти ветки по отдельности. Если dev1 и dev2 хотят взаимодействовать между собой, в процессе разработки, то они делают это по тому же принципу - через свои public репозитории. Нет необходимости загаживать центральный репозиторий лишним хламом. ИМХО.

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

# test.sh
# Кодировка ANSI.
# © Андрей Бушман
# ВАЖНО! Этот скрипт следует запускать из консоли Git Bash.
# Скрипт относится к моему комментарию со странички
# http://autolisp.ru/2015/04/27/sourcetree-branches-2/
# Этот код показывает, как test1 получил кашу вместо возможности тестировать
# отдельные ветки индивидуально и то, как это должно было делаться.

# Все наши эксперименты будем выполнять в подкаталоге ./kulik
cd kulik
# Создаём голый серверный репозиторий и на его основе 4 рабочих.
git init --bare server
git clone server dev1
git clone server dev2
git clone server dev3
git clone server test1

# юзер dev1 в ветке master создаёт файл Dev1master.txt, редактирует его, делает
# коммит и заливает изменения на центральный репозиторий
cd dev1
echo Dev1 \| master > Dev1master.txt
git add Dev1master.txt
git commit -m "dev1 master"
git push origin master

# юзеры dev2, dev3 и test1 синхронизируют свои рабочие репозитории с центральным
cd ../dev2
git pull --all
cd ../dev3
git pull --all
cd ../test1
git pull --all

# юзер dev1 создаёт ветку Dev1Br#1 и новый файл (Dev1br1.txt) в ней. Делает
# коммит, после чего новую ветку заливает на центральный репозиторий.
cd ../dev1
git checkout -b Dev1Br#1
echo 2>Dev1br1.txt
git add Dev1br1.txt
git commit -m "Dev1Br#1 commit#1"
git push origin Dev1Br#1

# юзер dev3 создаёт ветку Dev3Br#1 и новый файл (Dev3br1.txt) в ней. Делает
# коммит, после чего новую ветку заливает на центральный репозиторий.
cd ../dev3
git checkout -b Dev3Br#1
echo 2>Dev3br1.txt
git add Dev3br1.txt
git commit -m "Dev3Br#1 commit#1"
git push origin Dev3Br#1

# юзер test1 забирает все изменения из центрального репозитория (origin) для
# тестирования, но не заливает их в свой рабочий репозиторий (при желании, он
# мог бы и залить их в рабочий репозиторий, но в данном случае это не
# обязательно). Тем более он не делает никаких слияний (как это сделал Алексей).
# test1 будет лишь тестировать ветки origin/Dev1Br#1 и origin/Dev3Br#1 ПО
# ОТДЕЛЬНОСТИ, дабы выдавать замечания отдельно для dev1 и отдельно для dev3.
cd ../test1
git fetch origin
# переключился на ветку Dev1Br#1
git checkout origin/Dev1Br#1
# смотрит состав файлов
echo test1: files of the origin/Dev1Br#1 branch:
ls
# переключился на ветку Dev3Br#1
git checkout origin/Dev3Br#1
# смотрит состав файлов
echo test1: files of the origin/Dev3Br#1 branch:
ls

# ==============================================================================
# Как видим - мы не получили той каши, которую получил Алексей для test1,
# непонятно зачем объединив ветки Dev1Br#1 и Dev3Br#1 с веткой origin своего
# рабочего репозитория.
#
# Продемонстрированный мною выше код не выполняет этого слияния (за
# ненадобностью). test1 спокойно переключается между ветками origin/Dev1Br#1 и
# origin/Dev3Br#1 выполняя их раздельное тестирование.
#
# test1 может потестить ветки не заливая их себе в рабочий репозиторий. Он так
# же может выполнять в них коммиты и, если в дальнейщем примет такое решение -
# залить их себе в рабочий репозиторий не объединяя их при этом (за
# ненадобностью) со своей веткой origin.
# ==============================================================================

# смотрим список ВСЕХ веток , доступных test1 в его рабочем репозитории (в т.ч.
# и ветки центрального репозитория, не слитые в рабочий репозиторий).
git branch -a

# Если test1 захотел бы залить себе в рабочий репозиторий все текущие изменения,
# присутствующие на сервере, то он вместо команды
#   git fetch origin
# выполнил бы сразу команду
#   git pull --all
# А если бы он к тому же захотел бы сделать то, что сделал Алексей, т.е. слить
# ветки origin/Dev1Br#1 и origin/Dev3Br#1 в ветку origin, то затем test1
# выполнил бы следующее:
#   git checkout master
#   git merge origin/Dev1Br#1
#   git merge origin/Dev3Br#1
# В результате он бы получил то же самое, что и Алексей, т.е. полную кашу...

# юзер dev2 вносит изменение в файл Dev1master.txt ветки master. Затем делает
# коммит и заливает изменения в центральный репозиторий.
cd ../dev2
git pull --all
echo Dev2 \| master >> Dev1master.txt
git commit -am "dev2master commit#1"
git push origin master
# смотрим содержимое файла Dev1master.txt текущей ветки (origin) рабочего
# репозитория dev2
cat Dev1master.txt

# юзер dev1 заливает себе все текущие изменения с центрального репозитория.
# Затем переключается на ветку master и смотрит содержимое файла Dev1master.txt
cd ../dev1
git checkout master
git pull --all
cat Dev1master.txt

# юзер dev3 заливает себе все текущие изменения с центрального репозитория.
# Затем переключается на ветку master и смотрит содержимое файла Dev1master.txt
cd ../dev3
git checkout master
git pull --all
cat Dev1master.txt

# юзер test1 заливает себе все текущие изменения с центрального репозитория.
# Затем переключается на ветку master и смотрит содержимое файла Dev1master.txt
cd ../test1
git checkout master
git pull --all
cat Dev1master.txt 


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

bushm@DESKTOP-ISD2NUH MINGW64 /d/sandbox
$ /d/sandbox/test.sh
Initialized empty Git repository in D:/sandbox/kulik/server/
Cloning into 'dev1'...
warning: You appear to have cloned an empty repository.
done.
Cloning into 'dev2'...
warning: You appear to have cloned an empty repository.
done.
Cloning into 'dev3'...
warning: You appear to have cloned an empty repository.
done.
Cloning into 'test1'...
warning: You appear to have cloned an empty repository.
done.
warning: LF will be replaced by CRLF in Dev1master.txt.
The file will have its original line endings in your working directory.
[master (root-commit) a685643] dev1 master
warning: LF will be replaced by CRLF in Dev1master.txt.
The file will have its original line endings in your working directory.
 1 file changed, 1 insertion(+)
 create mode 100644 Dev1master.txt
Counting objects: 3, done.
Writing objects: 100% (3/3), 235 bytes | 0 bytes/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To D:/sandbox/kulik/server
 * [new branch]      master -> master
Fetching origin
remote: Counting objects: 3, done.
remote: Total 3 (delta 0), reused 0 (delta 0)
Unpacking objects: 100% (3/3), done.
From D:/sandbox/kulik/server
 * [new branch]      master     -> origin/master
Fetching origin
remote: Counting objects: 3, done.
remote: Total 3 (delta 0), reused 0 (delta 0)
Unpacking objects: 100% (3/3), done.
From D:/sandbox/kulik/server
 * [new branch]      master     -> origin/master
Fetching origin
remote: Counting objects: 3, done.
remote: Total 3 (delta 0), reused 0 (delta 0)
Unpacking objects: 100% (3/3), done.
From D:/sandbox/kulik/server
 * [new branch]      master     -> origin/master
Switched to a new branch 'Dev1Br#1'

[Dev1Br#1 8d3df6c] Dev1Br#1 commit#1
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 Dev1br1.txt
Counting objects: 3, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 283 bytes | 0 bytes/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To D:/sandbox/kulik/server
 * [new branch]      Dev1Br#1 -> Dev1Br#1
Switched to a new branch 'Dev3Br#1'

[Dev3Br#1 959a19b] Dev3Br#1 commit#1
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 Dev3br1.txt
Counting objects: 3, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 285 bytes | 0 bytes/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To D:/sandbox/kulik/server
 * [new branch]      Dev3Br#1 -> Dev3Br#1
remote: Counting objects: 5, done.
remote: Compressing objects: 100% (4/4), done.
remote: Total 5 (delta 1), reused 0 (delta 0)
Unpacking objects: 100% (5/5), done.
From D:/sandbox/kulik/server
 * [new branch]      Dev1Br#1   -> origin/Dev1Br#1
 * [new branch]      Dev3Br#1   -> origin/Dev3Br#1
Note: checking out 'origin/Dev1Br#1'.

You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by performing another checkout.

If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -b with the checkout command again. Example:

  git checkout -b <new-branch-name>

HEAD is now at 8d3df6c... Dev1Br#1 commit#1
test1: files of the origin/Dev1Br#1 branch:
Dev1br1.txt  Dev1master.txt
Previous HEAD position was 8d3df6c... Dev1Br#1 commit#1
HEAD is now at 959a19b... Dev3Br#1 commit#1
test1: files of the origin/Dev3Br#1 branch:
Dev1master.txt  Dev3br1.txt
* (HEAD detached at origin/Dev3Br#1)
  master
  remotes/origin/Dev1Br#1
  remotes/origin/Dev3Br#1
  remotes/origin/master
Fetching origin
remote: Counting objects: 5, done.
remote: Compressing objects: 100% (4/4), done.
remote: Total 5 (delta 1), reused 0 (delta 0)
Unpacking objects: 100% (5/5), done.
From D:/sandbox/kulik/server
 * [new branch]      Dev1Br#1   -> origin/Dev1Br#1
 * [new branch]      Dev3Br#1   -> origin/Dev3Br#1
Already up-to-date.
warning: LF will be replaced by CRLF in Dev1master.txt.
The file will have its original line endings in your working directory.
[master warning: LF will be replaced by CRLF in Dev1master.txt.
The file will have its original line endings in your working directory.
363d1f3] dev2master commit#1
warning: LF will be replaced by CRLF in Dev1master.txt.
The file will have its original line endings in your working directory.
 1 file changed, 1 insertion(+)
Counting objects: 3, done.
Writing objects: 100% (3/3), 275 bytes | 0 bytes/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To D:/sandbox/kulik/server
   a685643..363d1f3  master -> master
Dev1 | master
Dev2 | master
Switched to branch 'master'
Your branch is up-to-date with 'origin/master'.
Fetching origin
remote: Counting objects: 6, done.
remote: Compressing objects: 100% (3/3), done.
remote: Total 6 (delta 1), reused 0 (delta 0)
Unpacking objects: 100% (6/6), done.
From D:/sandbox/kulik/server
   a685643..363d1f3  master     -> origin/master
 * [new branch]      Dev3Br#1   -> origin/Dev3Br#1
Updating a685643..363d1f3
Fast-forward
 Dev1master.txt | 1 +
 1 file changed, 1 insertion(+)
Dev1 | master
Dev2 | master
Switched to branch 'master'
Your branch is up-to-date with 'origin/master'.
Fetching origin
remote: Counting objects: 6, done.
remote: Compressing objects: 100% (3/3), done.
remote: Total 6 (delta 1), reused 0 (delta 0)
Unpacking objects: 100% (6/6), done.
From D:/sandbox/kulik/server
   a685643..363d1f3  master     -> origin/master
 * [new branch]      Dev1Br#1   -> origin/Dev1Br#1
Updating a685643..363d1f3
Fast-forward
 Dev1master.txt | 1 +
 1 file changed, 1 insertion(+)
Dev1 | master
Dev2 | master
Previous HEAD position was 959a19b... Dev3Br#1 commit#1
Switched to branch 'master'
Your branch is up-to-date with 'origin/master'.
Fetching origin
remote: Counting objects: 3, done.
remote: Total 3 (delta 0), reused 0 (delta 0)
Unpacking objects: 100% (3/3), done.
From D:/sandbox/kulik/server
   a685643..363d1f3  master     -> origin/master
Updating a685643..363d1f3
Fast-forward
 Dev1master.txt | 1 +
 1 file changed, 1 insertion(+)
Dev1 | master
Dev2 | master

bushm@DESKTOP-ISD2NUH MINGW64 /d/sandbox
$

Сайт о Git для Windows.

Некоторое время назад создал сайт, на котором выкладываю материалы по работе с Git для Windows. Дополнительно присутствует материал о различных "подводных камнях", с которыми мне пришлось столкнуться на практике, а так же о способах их обхода. Ресурс редактируется и дополняется по мере оформления материала. Адрес сайта: http://www.git-for-win.red-bee.ru

Git & Unicode

Начиная с версии V1.7.10 Git for Windows поддерживает кодировку Unicode.

Имена файлов и каталогов, выполненные кирилицей, в Git for Windows могут отображаться, например так:


Чтобы это исправить, следует в консоли Git установить используемым шрифт TrueType, например Lucida Console или Consolas:


И произвести ряд изменений в настройках Git, посредством запуска команд:

git config --global core.quotepath off
git config --global --unset i18n.logoutputencoding
git config --global --unset i18n.commitencoding
git config --global --unset svn.pathnameencoding

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



Источник информации здесь.

Англоязычный вариант книги Pro Git здесь (pdf формат).
Русский перевод книги Pro Git здесь (pdf формат).

P.S. Если вам потребовалось в Git for Windows для операции git commit назначить иной текстовый редактор, путь к exe файлу которого содержит пробелы - в этом случае, при указании полного пути к exe файлу, следует внутри кавычек одного типа, дополнительно указывать кавычки другого типа. Т.е. либо одинарные кавычки упаковывать в двойные, либо наоборот - двойные кавычки упаковывать в одинарные. В общем, в подобных случаях следует использовать любой из следующих вариантов:

git config --global core.editor "'C:Program FilesNotepad++notepad++.exe'"
git config --global core.editor '"C:Program FilesNotepad++notepad++.exe"'