Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gitflow
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
tools
gitflow
Commits
6d74722d
Commit
6d74722d
authored
Feb 21, 2010
by
Vincent Driessen
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'feature/init-errors' into develop
parents
b3e89fe5
ef43cbd6
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
302 additions
and
77 deletions
+302
-77
git-flow
git-flow
+0
-9
git-flow-feature
git-flow-feature
+12
-9
git-flow-hotfix
git-flow-hotfix
+6
-3
git-flow-init
git-flow-init
+193
-33
git-flow-release
git-flow-release
+6
-3
git-flow-support
git-flow-support
+5
-2
gitflow-common
gitflow-common
+80
-18
No files found.
git-flow
View file @
6d74722d
...
...
@@ -19,11 +19,6 @@ if [ "$DEBUG" = "yes" ]; then
fi
export
GITFLOW_DIR
=
$(
dirname
"
$0
"
)
export
GIT_DIR
=
$(
git rev-parse
--git-dir
)
export
MASTER_BRANCH
=
$(
git config
--get
gitflow.branch.master
||
echo
master
)
export
DEVELOP_BRANCH
=
$(
git config
--get
gitflow.branch.develop
||
echo
develop
)
export
ORIGIN
=
$(
git config
--get
gitflow.origin
||
echo
origin
)
export
README
=
$(
git config
--get
gitflow.readme
||
echo
README
)
usage
()
{
echo
"usage: git flow <subcommand>"
...
...
@@ -62,10 +57,6 @@ main() {
exit
1
fi
if
!
git rev-parse
--git-dir
>
/dev/null
;
then
die
"Not a git repository"
fi
# run command
.
"
$GITFLOW_DIR
/git-flow-
$SUBCOMMAND
"
FLAGS_PARENT
=
"git flow
$SUBCOMMAND
"
...
...
git-flow-feature
View file @
6d74722d
...
...
@@ -12,7 +12,10 @@
# Copyright (c) 2010 by Benedikt Böhm
#
PREFIX=$(git config --get gitflow.prefix.feature || echo feature/)
gitflow_require_git_repo
gitflow_require_initialized
gitflow_load_settings
PREFIX=$(git config --get gitflow.prefix.feature)
usage() {
echo "usage: git flow feature [list] [-v]"
...
...
@@ -35,7 +38,7 @@ cmd_list() {
local feature_branches
local current_branch
local short_names
feature_branches=$(echo "$
LOCAL_BRANCHES
" | grep "^$PREFIX")
feature_branches=$(echo "$
(gitflow_local_branches)
" | grep "^$PREFIX")
if [ -z "$feature_branches" ]; then
warn "No feature branches exist."
exit 0
...
...
@@ -184,7 +187,7 @@ cmd_finish() {
gitflow_require_branch "$BRANCH"
# detect if we're restoring from a merge conflict
if [ -f "$GIT_DIR/.gitflow/MERGE_BASE" ]; then
if [ -f "$
DOT_
GIT_DIR/.gitflow/MERGE_BASE" ]; then
#
# TODO: detect that we're working on the correct branch here!
# The user need not necessarily have given the same $NAME twice here
...
...
@@ -195,20 +198,20 @@ cmd_finish() {
# exit code for "unmerged changes in working tree", which we should
# actually be testing for here
if gitflow_test_clean_working_tree; then
FINISH_BASE=$(cat "$GIT_DIR/.gitflow/MERGE_BASE")
FINISH_BASE=$(cat "$
DOT_
GIT_DIR/.gitflow/MERGE_BASE")
# Since the working tree is now clean, either the user did a
# succesfull merge manually, or the merge was cancelled.
# We detect this using gitflow_is_branch_merged_into()
if gitflow_is_branch_merged_into "$BRANCH" "$FINISH_BASE"; then
rm -f "$GIT_DIR/.gitflow/MERGE_BASE"
rm -f "$
DOT_
GIT_DIR/.gitflow/MERGE_BASE"
helper_finish_cleanup
exit 0
else
# If the user cancelled the merge and decided to wait until later,
# that's fine. But we have to acknowledge this by removing the
# MERGE_BASE file and continuing normal execution of the finish
rm -f "$GIT_DIR/.gitflow/MERGE_BASE"
rm -f "$
DOT_
GIT_DIR/.gitflow/MERGE_BASE"
fi
else
echo
...
...
@@ -231,7 +234,7 @@ cmd_finish() {
git fetch -q "$ORIGIN" "$BRANCH"
fi
if has "$ORIGIN/$BRANCH" "$
REMOTE_BRANCHES
"; then
if has "$ORIGIN/$BRANCH" "$
(gitflow_remote_branches)
"; then
gitflow_require_branches_equal "$BRANCH" "$ORIGIN/$BRANCH"
fi
gitflow_require_branches_equal "$DEVELOP_BRANCH" "$ORIGIN/$DEVELOP_BRANCH"
...
...
@@ -258,8 +261,8 @@ cmd_finish() {
if [ $? -ne 0 ]; then
# oops.. we have a merge conflict!
# write the given $DEVELOP_BRANCH to a temporary file (we need it later)
mkdir -p "$GIT_DIR/.gitflow"
echo "$DEVELOP_BRANCH" > "$GIT_DIR/.gitflow/MERGE_BASE"
mkdir -p "$
DOT_
GIT_DIR/.gitflow"
echo "$DEVELOP_BRANCH" > "$
DOT_
GIT_DIR/.gitflow/MERGE_BASE"
echo
echo "There were merge conflicts. To resolve the merge conflict manually, use:"
echo " git mergetool"
...
...
git-flow-hotfix
View file @
6d74722d
...
...
@@ -12,8 +12,11 @@
# Copyright (c) 2010 by Benedikt Böhm
#
gitflow_require_git_repo
gitflow_require_initialized
gitflow_load_settings
VERSION_PREFIX=$(git config --get gitflow.prefix.versiontag)
PREFIX=$(git config --get gitflow.prefix.hotfix
|| echo hotfix/
)
PREFIX=$(git config --get gitflow.prefix.hotfix)
usage() {
echo "usage: git flow hotfix [list] [-v]"
...
...
@@ -32,7 +35,7 @@ cmd_list() {
local hotfix_branches
local current_branch
local short_names
hotfix_branches=$(echo "$
LOCAL_BRANCHES
" | grep "^$PREFIX")
hotfix_branches=$(echo "$
(gitflow_local_branches)
" | grep "^$PREFIX")
if [ -z "$hotfix_branches" ]; then
warn "No hotfix branches exist."
exit 0
...
...
@@ -113,7 +116,7 @@ require_base_is_on_master() {
}
require_no_existing_hotfix_branches() {
local hotfix_branches=$(echo "$
LOCAL_BRANCHES
" | grep "^$PREFIX")
local hotfix_branches=$(echo "$
(gitflow_local_branches)
" | grep "^$PREFIX")
local first_branch=$(echo ${hotfix_branches} | head -n1)
first_branch=${first_branch#$PREFIX}
[ -z "$hotfix_branches" ] || \
...
...
git-flow-init
View file @
6d74722d
...
...
@@ -16,59 +16,219 @@ usage() {
echo "usage: git flow init"
}
parse_args() {
# parse options
FLAGS "$@" || exit $?
eval set -- "${FLAGS_ARGV}"
}
# Default entry when no SUBACTION is given
cmd_default() {
echo
echo "Summary of actions:
"
DEFINE_boolean force false 'force setting of gitflow branches, even if already configured' f
parse_args "$@
"
if ! git rev-parse --git-dir >/dev/null 2>&1; then
git init --quiet
echo "- A new git repository at $PWD was created"
git init
else
# assure that we are not working in a repo with local changes
git_repo_is_headless || gitflow_require_clean_working_tree
fi
if ! git rev-parse --quiet --verify HEAD >/dev/null 2>&1; then
touch "$README"
git add "$README"
git commit --quiet -m "initial commit"
if [ "$MASTER_BRANCH" != "master" ]; then
git branch -m master "$MASTER_BRANCH"
fi
echo "- An initial commit was created at branch '$MASTER_BRANCH'"
# running git flow init on an already initialized repo is fine
if gitflow_is_initialized && ! flag force; then
warn "Already initialized for gitflow."
warn "To force reinitialization, use: git flow init -f"
exit 0
fi
if ! git rev-parse --verify "$MASTER_BRANCH" >/dev/null 2>&1; then
die "Cannot find your master branch. Try: git branch -m <mymaster> $MASTER_BRANCH"
fi
local branch_count
local answer
gitflow_require_clean_working_tree
# add a master branch if no such branch exists yet
local master_branch
if gitflow_has_master_configured && ! flag force; then
master_branch=$(git config --get gitflow.branch.master)
else
# Two cases are distinguished:
# 1. A fresh git repo (without any branches)
# We will create a new master/develop branch for the user
# 2. Some branches do already exist
# We will disallow creation of new master/develop branches and
# rather allow to use existing branches for git-flow.
local default_suggestion
local should_check_existence
branch_count=$(gitflow_local_branches | wc -l)
if [ "$branch_count" -eq 0 ]; then
echo "No branches exist yet. Base branches must be created now."
should_check_existence=NO
default_suggestion=master
else
echo
echo "Which branch should be used for bringing forth production releases?"
gitflow_local_branches | sed 's/^.*$/ - &/g'
if git remote | grep -q "$ORIGIN"; then
git fetch -q "$ORIGIN"
gitflow_require_branches_equal "$MASTER_BRANCH" "$ORIGIN/$MASTER_BRANCH"
fi
should_check_existence=YES
default_suggestion=
for guess in 'production' 'main' 'master'; do
if gitflow_local_branch_exists "$guess"; then
default_suggestion="$guess"
break
fi
done
fi
if git rev-parse --verify "$DEVELOP_BRANCH" >/dev/null 2>&1; then
gitflow_require_branches_equal "$DEVELOP_BRANCH" "$ORIGIN/$DEVELOP_BRANCH"
else
git checkout -q -b "$DEVELOP_BRANCH" "$MASTER_BRANCH"
echo "- A new branch '$DEVELOP_BRANCH' was created"
echo "- You are now on branch '$DEVELOP_BRANCH'"
echo "Branch name for production releases: [$default_suggestion] \c"
read answer
master_branch=${answer:-$default_suggestion}
# check existence in case of an already existing repo
if [ "$should_check_existence" = "YES" ]; then
gitflow_local_branch_exists "$master_branch" || \
die "Local branch '$master_branch' does not exist."
fi
# store the name of the master branch
git config gitflow.branch.master "$master_branch"
fi
if ! git remote | grep -q "$ORIGIN"; then
if [ "$1" = "" ]; then
echo "- No remote location was added. Try: git remote add $ORIGIN <url>"
# add a develop branch if no such branch exists yet
local develop_branch
if gitflow_has_develop_configured && ! flag force; then
develop_branch=$(git config --get gitflow.branch.develop)
else
# Again, the same two cases as with the master selection are
# considered (fresh repo or repo that contains branches)
local default_suggestion
local should_check_existence
branch_count=$(gitflow_local_branches | grep -v "^${master_branch}\$" | wc -l)
if [ "$branch_count" -eq 0 ]; then
should_check_existence=NO
default_suggestion=develop
else
git remote add "$ORIGIN" "$1"
echo "- A new remote location '$1' was added"
echo
echo "Which branch should be used for integration of the \"next release\"?"
gitflow_local_branches | grep -v "^${master_branch}\$" | sed 's/^.*$/ - &/g'
should_check_existence=YES
default_suggestion=
for guess in 'develop' 'int' 'integration' 'master'; do
if gitflow_local_branch_exists "$guess"; then
default_suggestion="$guess"
break
fi
done
fi
echo "Branch name for \"next release\" development: [$default_suggestion] \c"
read answer
develop_branch=${answer:-$default_suggestion}
if [ "$master_branch" = "$develop_branch" ]; then
die "Production and integration branches should differ."
fi
# check existence in case of an already existing repo
if [ "$should_check_existence" = "YES" ]; then
gitflow_local_branch_exists "$develop_branch" || \
die "Local branch '$develop_branch' does not exist."
fi
# store the name of the develop branch
git config gitflow.branch.develop "$develop_branch"
fi
# Creation of HEAD
# ----------------
# We create a HEAD now, if it does not exist yet (in a fresh repo). We need
# it to be able to create new branches.
local created_gitflow_branch=0
if ! git rev-parse --quiet --verify HEAD >/dev/null 2>&1; then
git symbolic-ref HEAD "refs/heads/$master_branch"
git commit --allow-empty --quiet -m "Initial commit"
created_gitflow_branch=1
fi
# Creation of master
# ------------------
# At this point, there always is a master branch: either it existed already
# (and was picked interactively as the production branch) or it has just
# been created in a fresh repo
# Creation of develop
# -------------------
# The develop branch possibly does not exist yet. This is the case when,
# in a git init'ed repo with one or more commits, master was picked as the
# default production branch and develop was "created". We should create
# the develop branch now in that case (we base it on master, of course)
if ! gitflow_local_branch_exists "$develop_branch"; then
git branch "$develop_branch" "$master_branch"
created_gitflow_branch=1
fi
# assert the gitflow repo has been correctly initialized
gitflow_is_initialized
# switch to develop branch if its newly created
if [ $created_gitflow_branch -eq 1 ]; then
git checkout -q "$develop_branch"
fi
# finally, ask the user for naming conventions (branch and tag prefixes)
echo
echo "How to name your supporting branch prefixes?"
local prefix
# Feature branches
if ! git config --get gitflow.prefix.feature >/dev/null 2>&1 || flag force; then
default_suggestion=$(git config --get gitflow.prefix.feature || echo feature/)
echo "Feature branches? [$default_suggestion] \c"
read answer
[ "$answer" = "-" ] && prefix= || prefix=${answer:-$default_suggestion}
git config gitflow.prefix.feature "$prefix"
fi
if git remote | grep -q "$ORIGIN"; then
git push "$ORIGIN" "$MASTER_BRANCH" "$DEVELOP_BRANCH"
# Release branches
if ! git config --get gitflow.prefix.release >/dev/null 2>&1 || flag force; then
default_suggestion=$(git config --get gitflow.prefix.release || echo release/)
echo "Release branches? [$default_suggestion] \c"
read answer
[ "$answer" = "-" ] && prefix= || prefix=${answer:-$default_suggestion}
git config gitflow.prefix.release "$prefix"
fi
# Hotfix branches
if ! git config --get gitflow.prefix.hotfix >/dev/null 2>&1 || flag force; then
default_suggestion=$(git config --get gitflow.prefix.hotfix || echo hotfix/)
echo "Hotfix branches? [$default_suggestion] \c"
read answer
[ "$answer" = "-" ] && prefix= || prefix=${answer:-$default_suggestion}
git config gitflow.prefix.hotfix "$prefix"
fi
# Support branches
if ! git config --get gitflow.prefix.support >/dev/null 2>&1 || flag force; then
default_suggestion=$(git config --get gitflow.prefix.support || echo support/)
echo "Support branches? [$default_suggestion] \c"
read answer
[ "$answer" = "-" ] && prefix= || prefix=${answer:-$default_suggestion}
git config gitflow.prefix.support "$prefix"
fi
# Version tag prefix
if ! git config --get gitflow.prefix.versiontag >/dev/null 2>&1 || flag force; then
default_suggestion=$(git config --get gitflow.prefix.versiontag || echo "")
echo "Version tag prefix? [$default_suggestion] \c"
read answer
[ "$answer" = "-" ] && prefix= || prefix=${answer:-$default_suggestion}
git config gitflow.prefix.versiontag "$prefix"
fi
# TODO: what to do with origin?
}
cmd_help() {
...
...
git-flow-release
View file @
6d74722d
...
...
@@ -12,8 +12,11 @@
# Copyright (c) 2010 by Benedikt Böhm
#
gitflow_require_git_repo
gitflow_require_initialized
gitflow_load_settings
VERSION_PREFIX=$(git config --get gitflow.prefix.versiontag)
PREFIX=$(git config --get gitflow.prefix.release
|| echo release/
)
PREFIX=$(git config --get gitflow.prefix.release)
usage() {
echo "usage: git flow release [list] [-v]"
...
...
@@ -43,7 +46,7 @@ cmd_list() {
local release_branches
local current_branch
local short_names
release_branches=$(echo "$
LOCAL_BRANCHES
" | grep "^$PREFIX")
release_branches=$(echo "$
(gitflow_local_branches)
" | grep "^$PREFIX")
if [ -z "$release_branches" ]; then
warn "No release branches exist."
exit 0
...
...
@@ -119,7 +122,7 @@ require_base_is_on_develop() {
}
require_no_existing_release_branches() {
local release_branches=$(echo "$
LOCAL_BRANCHES
" | grep "^$PREFIX")
local release_branches=$(echo "$
(gitflow_local_branches)
" | grep "^$PREFIX")
local first_branch=$(echo ${release_branches} | head -n1)
first_branch=${first_branch#$PREFIX}
[ -z "$release_branches" ] || \
...
...
git-flow-support
View file @
6d74722d
...
...
@@ -12,8 +12,11 @@
# Copyright (c) 2010 by Benedikt Böhm
#
gitflow_require_git_repo
gitflow_require_initialized
gitflow_load_settings
VERSION_PREFIX=$(git config --get gitflow.prefix.versiontag)
PREFIX=$(git config --get gitflow.prefix.support
|| echo support/
)
PREFIX=$(git config --get gitflow.prefix.support)
warn "note: The support subcommand is still very EXPERIMENTAL!"
warn "note: DO NOT use it in a production situation."
...
...
@@ -34,7 +37,7 @@ cmd_list() {
local support_branches
local current_branch
local short_names
support_branches=$(echo "$
LOCAL_BRANCHES
" | grep "^$PREFIX")
support_branches=$(echo "$
(gitflow_local_branches)
" | grep "^$PREFIX")
if [ -z "$support_branches" ]; then
warn "No support branches exist."
exit 0
...
...
gitflow-common
View file @
6d74722d
...
...
@@ -38,11 +38,46 @@ noflag() { local FLAG; eval FLAG='$FLAGS_'$1; [ $FLAG -ne $FLAGS_TRUE ]; }
# Git specific common functionality
#
# check if this repo has been inited for gitflow
gitflow_has_master_configured() {
local master=$(git config --get gitflow.branch.master)
[ "$master" != "" ] && gitflow_local_branch_exists "$master"
}
gitflow_has_develop_configured() {
local develop=$(git config --get gitflow.branch.develop)
[ "$develop" != "" ] && gitflow_local_branch_exists "$develop"
}
gitflow_has_prefixes_configured() {
git config --get gitflow.prefix.feature >/dev/null 2>&1 && \
git config --get gitflow.prefix.release >/dev/null 2>&1 && \
git config --get gitflow.prefix.hotfix >/dev/null 2>&1 && \
git config --get gitflow.prefix.support >/dev/null 2>&1 && \
git config --get gitflow.prefix.versiontag >/dev/null 2>&1
}
gitflow_is_initialized() {
gitflow_has_master_configured && \
gitflow_has_develop_configured && \
[ "$(git config --get gitflow.branch.master)" != \
"$(git config --get gitflow.branch.develop)" ] && \
gitflow_has_prefixes_configured
}
# get all available branches
LOCAL_BRANCHES=$(git branch | sed 's/^[* ] //')
REMOTE_BRANCHES=$(git branch -r | sed 's/^[* ] //')
ALL_BRANCHES="$LOCAL_BRANCHES $REMOTE_BRANCHES"
ALL_TAGS=$(git tag)
gitflow_local_branches() { git branch | sed 's/^[* ] //'; }
gitflow_remote_branches() { git branch -r | sed 's/^[* ] //'; }
gitflow_all_branches() { ( git branch; git branch -r) | sed 's/^[* ] //'; }
gitflow_all_tags() { git tag; }
# loading settings that can be overridden using git config
gitflow_load_settings() {
export DOT_GIT_DIR=$(git rev-parse --git-dir >/dev/null 2>&1)
export MASTER_BRANCH=$(git config --get gitflow.branch.master)
export DEVELOP_BRANCH=$(git config --get gitflow.branch.develop)
export ORIGIN=$(git config --get gitflow.origin || echo origin)
}
#
# resolve_nameprefix
...
...
@@ -51,8 +86,8 @@ ALL_TAGS=$(git tag)
# $1 = name prefix to resolve
# $2 = branch prefix to use
#
# Searches branch names from
LOCAL_BRANCHES to look for a unique branch
# name whose name starts with the given name prefix.
# Searches branch names from
gitflow_local_branches() to look for a unique
#
branch
name whose name starts with the given name prefix.
#
# There are multiple exit codes possible:
# 0: The unambiguous full name of the branch is written to stdout
...
...
@@ -67,12 +102,12 @@ resolve_nameprefix() {
local num_matches
# first, check if there is a perfect match
if has "$
LOCAL_BRANCHES
" "$prefix$name"; then
if has "$
(gitflow_local_branches)
" "$prefix$name"; then
echo "$name"
return 0
fi
matches=$(echo "$
LOCAL_BRANCHES
" | grep "^$prefix$name")
matches=$(echo "$
(gitflow_local_branches)
" | grep "^$prefix$name")
num_matches=$(echo "$matches" | wc -l)
if [ -z "$matches" ]; then
# no prefix match, so take it literally
...
...
@@ -107,6 +142,22 @@ gitflow_test_clean_working_tree() {
fi
}
gitflow_require_git_repo() {
if ! git rev-parse --git-dir >/dev/null 2>&1; then
die "fatal: Not a git repository"
fi
}
gitflow_require_initialized() {
if ! gitflow_is_initialized; then
die "fatal: Not a gitflow-enabled repo yet. Please run \"git flow init\" first."
fi
}
git_repo_is_headless() {
! git rev-parse --quiet --verify HEAD >/dev/null 2>&1
}
gitflow_require_clean_working_tree() {
gitflow_test_clean_working_tree
local result=$?
...
...
@@ -118,40 +169,48 @@ gitflow_require_clean_working_tree() {
fi
}
gitflow_local_branch_exists() {
has $1 $(gitflow_local_branches)
}
gitflow_branch_exists() {
has $1 $(gitflow_all_branches)
}
gitflow_tag_exists() {
has $1 $(gitflow_all_tags)
}
gitflow_require_local_branch() {
if !
has $1 $LOCAL_BRANCHES
; then
if !
gitflow_local_branch_exists
; then
die "fatal: Local branch '$1' does not exist and is required."
fi
}
gitflow_require_remote_branch() {
if ! has $1 $
REMOTE_BRANCHES
; then
if ! has $1 $
(gitflow_remote_branches)
; then
die "Remote branch '$1' does not exist and is required."
fi
}
gitflow_require_branch() {
if ! has $1 $
ALL_BRANCHES
; then
if ! has $1 $
(gitflow_all_branches)
; then
die "Branch '$1' does not exist and is required."
fi
}
gitflow_require_branch_absent() {
if has $1 $
ALL_BRANCHES
; then
if has $1 $
(gitflow_all_branches)
; then
die "Branch '$1' already exists. Pick another name."
fi
}
gitflow_require_tag_absent() {
if has $1 $
ALL_TAGS
; then
if has $1 $
(gitflow_all_tags)
; then
die "Tag '$1' already exists. Pick another name."
fi
}
gitflow_tag_exists() {
has $1 $ALL_TAGS
}
#
# gitflow_test_branches_equal()
#
...
...
@@ -162,13 +221,16 @@ gitflow_tag_exists() {
# 1 First given branch needs fast-forwarding
# 2 Second given branch needs fast-forwarding
# 3 Branch needs a real merge
# 4 There is no merge base, i.e. the branches have no common ancestors
#
gitflow_test_branches_equal() {
local commit1=$(git rev-parse "$1")
local commit2=$(git rev-parse "$2")
if [ "$commit1" != "$commit2" ]; then
local base=$(git merge-base "$commit1" "$commit2")
if [ "$commit1" = "$base" ]; then
if [ $? -ne 0 ]; then
return 4
elif [ "$commit1" = "$base" ]; then
return 1
elif [ "$commit2" = "$base" ]; then
return 2
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment